syndicate-2017/dist/syndicate.js

30393 lines
2.1 MiB
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(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<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
},{}],2:[function(require,module,exports){
(function (global){
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* @license MIT
*/
/* eslint-disable no-proto */
'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 ' + str + '>'
}
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 ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
};
/*
var zeros = [];
var groupSizes = [];
var groupBases = [];
var s = '';
var i = -1;
while (++i < BN.wordSize) {
zeros[i] = s;
s += '0';
}
groupSizes[0] = 0;
groupSizes[1] = 0;
groupBases[0] = 0;
groupBases[1] = 0;
var base = 2 - 1;
while (++base < 36 + 1) {
var groupSize = 0;
var groupBase = 1;
while (groupBase < (1 << BN.wordSize) / base) {
groupBase *= base;
groupSize += 1;
}
groupSizes[base] = groupSize;
groupBases[base] = groupBase;
}
*/
var zeros = [
'',
'0',
'00',
'000',
'0000',
'00000',
'000000',
'0000000',
'00000000',
'000000000',
'0000000000',
'00000000000',
'000000000000',
'0000000000000',
'00000000000000',
'000000000000000',
'0000000000000000',
'00000000000000000',
'000000000000000000',
'0000000000000000000',
'00000000000000000000',
'000000000000000000000',
'0000000000000000000000',
'00000000000000000000000',
'000000000000000000000000',
'0000000000000000000000000'
];
var groupSizes = [
0, 0,
25, 16, 12, 11, 10, 9, 8,
8, 7, 7, 7, 7, 6, 6,
6, 6, 6, 6, 6, 5, 5,
5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5
];
var groupBases = [
0, 0,
33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
];
BN.prototype.toString = function toString (base, padding) {
base = base || 10;
padding = padding | 0 || 1;
var out;
if (base === 16 || base === 'hex') {
out = '';
var off = 0;
var carry = 0;
for (var i = 0; i < this.length; i++) {
var w = this.words[i];
var word = (((w << off) | carry) & 0xffffff).toString(16);
carry = (w >>> (24 - off)) & 0xffffff;
if (carry !== 0 || i !== this.length - 1) {
out = zeros[6 - word.length] + word + out;
} else {
out = word + out;
}
off += 2;
if (off >= 26) {
off -= 26;
i--;
}
}
if (carry !== 0) {
out = carry.toString(16) + out;
}
while (out.length % padding !== 0) {
out = '0' + out;
}
if (this.negative !== 0) {
out = '-' + out;
}
return out;
}
if (base === (base | 0) && base >= 2 && base <= 36) {
// var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
var groupSize = groupSizes[base];
// var groupBase = Math.pow(base, groupSize);
var groupBase = groupBases[base];
out = '';
var c = this.clone();
c.negative = 0;
while (!c.isZero()) {
var r = c.modn(groupBase).toString(base);
c = c.idivn(groupBase);
if (!c.isZero()) {
out = zeros[groupSize - r.length] + r + out;
} else {
out = r + out;
}
}
if (this.isZero()) {
out = '0' + out;
}
while (out.length % padding !== 0) {
out = '0' + out;
}
if (this.negative !== 0) {
out = '-' + out;
}
return out;
}
assert(false, 'Base should be between 2 and 36');
};
BN.prototype.toNumber = function toNumber () {
var 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 '<EC Point Infinity>';
return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
' y: ' + this.y.fromRed().toString(16, 2) +
' z: ' + this.z.fromRed().toString(16, 2) + '>';
};
Point.prototype.isInfinity = function isInfinity() {
// XXX This code assumes that zero is always zero in red
return this.x.cmpn(0) === 0 &&
this.y.cmp(this.z) === 0;
};
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 '<EC Point Infinity>';
return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
' z: ' + this.z.fromRed().toString(16, 2) + '>';
};
Point.prototype.isInfinity = function isInfinity() {
// XXX This code assumes that zero is always zero in red
return this.z.cmpn(0) === 0;
};
Point.prototype.dbl = function dbl() {
// http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3
// 2M + 2S + 4A
// A = X1 + Z1
var a = this.x.redAdd(this.z);
// AA = A^2
var aa = a.redSqr();
// B = X1 - Z1
var b = this.x.redSub(this.z);
// BB = B^2
var bb = b.redSqr();
// C = AA - BB
var c = aa.redSub(bb);
// X3 = AA * BB
var nx = aa.redMul(bb);
// Z3 = C * (BB + A24 * C)
var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c)));
return this.curve.point(nx, nz);
};
Point.prototype.add = function add() {
throw new Error('Not supported on Montgomery curve');
};
Point.prototype.diffAdd = function diffAdd(p, diff) {
// http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3
// 4M + 2S + 6A
// A = X2 + Z2
var a = this.x.redAdd(this.z);
// B = X2 - Z2
var b = this.x.redSub(this.z);
// C = X3 + Z3
var c = p.x.redAdd(p.z);
// D = X3 - Z3
var d = p.x.redSub(p.z);
// DA = D * A
var da = d.redMul(a);
// CB = C * B
var cb = c.redMul(b);
// X5 = Z1 * (DA + CB)^2
var nx = diff.z.redMul(da.redAdd(cb).redSqr());
// Z5 = X1 * (DA - CB)^2
var nz = diff.x.redMul(da.redISub(cb).redSqr());
return this.curve.point(nx, nz);
};
Point.prototype.mul = function mul(k) {
var t = k.clone();
var a = this; // (N / 2) * Q + Q
var b = this.curve.point(null, null); // (N / 2) * Q
var c = this; // Q
for (var bits = []; t.cmpn(0) !== 0; t.iushrn(1))
bits.push(t.andln(1));
for (var i = bits.length - 1; i >= 0; i--) {
if (bits[i] === 0) {
// N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q
a = a.diffAdd(b, c);
// N * Q = 2 * ((N / 2) * Q + Q))
b = b.dbl();
} else {
// N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q)
b = a.diffAdd(b, c);
// N * Q + Q = 2 * ((N / 2) * Q + Q)
a = a.dbl();
}
}
return b;
};
Point.prototype.mulAdd = function mulAdd() {
throw new Error('Not supported on Montgomery curve');
};
Point.prototype.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 '<EC Point Infinity>';
return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
' y: ' + this.y.fromRed().toString(16, 2) + '>';
};
Point.prototype.isInfinity = function isInfinity() {
return this.inf;
};
Point.prototype.add = function add(p) {
// O + P = P
if (this.inf)
return p;
// P + O = P
if (p.inf)
return this;
// P + P = 2P
if (this.eq(p))
return this.dbl();
// P + (-P) = O
if (this.neg().eq(p))
return this.curve.point(null, null);
// P + Q = O
if (this.x.cmp(p.x) === 0)
return this.curve.point(null, null);
var c = this.y.redSub(p.y);
if (c.cmpn(0) !== 0)
c = c.redMul(this.x.redSub(p.x).redInvm());
var nx = c.redSqr().redISub(this.x).redISub(p.x);
var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
return this.curve.point(nx, ny);
};
Point.prototype.dbl = function dbl() {
if (this.inf)
return this;
// 2P = O
var ys1 = this.y.redAdd(this.y);
if (ys1.cmpn(0) === 0)
return this.curve.point(null, null);
var a = this.curve.a;
var x2 = this.x.redSqr();
var dyinv = ys1.redInvm();
var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv);
var nx = c.redSqr().redISub(this.x.redAdd(this.x));
var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
return this.curve.point(nx, ny);
};
Point.prototype.getX = function getX() {
return this.x.fromRed();
};
Point.prototype.getY = function getY() {
return this.y.fromRed();
};
Point.prototype.mul = function mul(k) {
k = new BN(k, 16);
if (this._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 '<EC JPoint Infinity>';
return '<EC JPoint x: ' + this.x.toString(16, 2) +
' y: ' + this.y.toString(16, 2) +
' z: ' + this.z.toString(16, 2) + '>';
};
JPoint.prototype.isInfinity = function isInfinity() {
// XXX This code assumes that zero is always zero in red
return this.z.cmpn(0) === 0;
};
},{"../../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 '<Key priv: ' + (this.priv && this.priv.toString(16, 2)) +
' pub: ' + (this.pub && this.pub.inspect()) + ' >';
};
},{"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<Byte>} [params.secret] - secret seed bytes
* @param {Point} [params.pub] - public key point (aka `A` in eddsa terms)
* @param {Array<Byte>} [params.pub] - public key point encoded as bytes
*
*/
function KeyPair(eddsa, params) {
this.eddsa = eddsa;
this._secret = parseBytes(params.secret);
if (eddsa.isPoint(params.pub))
this._pub = params.pub;
else
this._pubBytes = parseBytes(params.pub);
}
KeyPair.fromPublic = function fromPublic(eddsa, pub) {
if (pub instanceof KeyPair)
return pub;
return new KeyPair(eddsa, { pub: pub });
};
KeyPair.fromSecret = function fromSecret(eddsa, secret) {
if (secret instanceof KeyPair)
return secret;
return new KeyPair(eddsa, { secret: secret });
};
KeyPair.prototype.secret = function secret() {
return this._secret;
};
cachedProperty(KeyPair, 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<Bytes>|Object} sig -
* @param {Array<Bytes>|Point} [sig.R] - R point as Point or bytes
* @param {Array<Bytes>|bn} [sig.S] - S scalar as bn or bytes
* @param {Array<Bytes>} [sig.Rencoded] - R point encoded
* @param {Array<Bytes>} [sig.Sencoded] - S scalar encoded
*/
function Signature(eddsa, sig) {
this.eddsa = eddsa;
if (typeof sig !== 'object')
sig = parseBytes(sig);
if (Array.isArray(sig)) {
sig = {
R: sig.slice(0, eddsa.encodingLength),
S: sig.slice(eddsa.encodingLength)
};
}
assert(sig.R && sig.S, 'Signature without R or S');
if (eddsa.isPoint(sig.R))
this._R = sig.R;
if (sig.S instanceof BN)
this._S = sig.S;
this._Rencoded = Array.isArray(sig.R) ? sig.R : sig.Rencoded;
this._Sencoded = Array.isArray(sig.S) ? sig.S : sig.Sencoded;
}
cachedProperty(Signature, 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 <feross@feross.org> <http://feross.org>
* 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';
/*<replacement>*/
var objectKeys = Object.keys || function (obj) {
var keys = [];
for (var key in obj) keys.push(key);
return keys;
}
/*</replacement>*/
module.exports = Duplex;
/*<replacement>*/
var processNextTick = require('process-nextick-args');
/*</replacement>*/
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
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');
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
util.inherits(PassThrough, Transform);
function PassThrough(options) {
if (!(this instanceof PassThrough))
return new PassThrough(options);
Transform.call(this, options);
}
PassThrough.prototype._transform = function(chunk, encoding, cb) {
cb(null, chunk);
};
},{"./_stream_transform":207,"core-util-is":209,"inherits":199}],206:[function(require,module,exports){
(function (process){
'use strict';
module.exports = Readable;
/*<replacement>*/
var processNextTick = require('process-nextick-args');
/*</replacement>*/
/*<replacement>*/
var isArray = require('isarray');
/*</replacement>*/
/*<replacement>*/
var Buffer = require('buffer').Buffer;
/*</replacement>*/
Readable.ReadableState = ReadableState;
var EE = require('events');
/*<replacement>*/
var EElistenerCount = function(emitter, type) {
return emitter.listeners(type).length;
};
/*</replacement>*/
/*<replacement>*/
var Stream;
(function (){try{
Stream = require('st' + 'ream');
}catch(_){}finally{
if (!Stream)
Stream = require('events').EventEmitter;
}}())
/*</replacement>*/
var Buffer = require('buffer').Buffer;
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
/*<replacement>*/
var debugUtil = require('util');
var debug;
if (debugUtil && debugUtil.debuglog) {
debug = debugUtil.debuglog('stream');
} else {
debug = function () {};
}
/*</replacement>*/
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');
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
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;
/*<replacement>*/
var processNextTick = require('process-nextick-args');
/*</replacement>*/
/*<replacement>*/
var Buffer = require('buffer').Buffer;
/*</replacement>*/
Writable.WritableState = WritableState;
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
/*<replacement>*/
var internalUtil = {
deprecate: require('util-deprecate')
};
/*</replacement>*/
/*<replacement>*/
var Stream;
(function (){try{
Stream = require('st' + 'ream');
}catch(_){}finally{
if (!Stream)
Stream = require('events').EventEmitter;
}}())
/*</replacement>*/
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^321.
//
// 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 Dataspace = require('./dataspace.js').Dataspace;
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 () {
Dataspace.stateChange(Patch.sub([$Ack, this.id], this.metaLevel));
Dataspace.send([$Ack, this.id], this.metaLevel);
};
Ack.prototype.disarm = function () {
Dataspace.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;
},{"./dataspace.js":223,"./patch.js":230,"./randomid.js":231,"./route.js":233}],222:[function(require,module,exports){
'use strict';
var Immutable = require('immutable');
var Dataspace = require('./dataspace.js').Dataspace;
var Mux = require('./mux.js');
var Patch = require('./patch.js');
var Route = require('./route.js');
var Util = require('./util.js');
//---------------------------------------------------------------------------
function spawnActor(state, bootFn) {
Dataspace.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()) {
Dataspace.exit();
}
};
//---------------------------------------------------------------------------
function createFacet() {
return new Facet(Dataspace.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);
Dataspace.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);
});
Dataspace.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);
});
Dataspace.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;
},{"./dataspace.js":223,"./mux.js":229,"./patch.js":230,"./route.js":233,"./util.js":235,"immutable":220}],223:[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 terminateDataspace() {
return { type: 'terminateDataspace' };
}
/*---------------------------------------------------------------------------*/
/* Dataspace */
function Dataspace(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
Dataspace.stack = Immutable.List();
Dataspace.current = function () {
return Dataspace.stack.last().dataspace;
};
Dataspace.activePid = function () {
return Dataspace.stack.last().activePid;
};
Dataspace.activeBehavior = function () {
var entry = Dataspace.stack.last();
var p = entry.dataspace.processTable.get(entry.activePid);
return p ? p.behavior : null;
};
Dataspace.withDataspaceStack = function (stack, f) {
var oldStack = Dataspace.stack;
Dataspace.stack = stack;
var result;
try {
result = f();
} catch (e) {
Dataspace.stack = oldStack;
throw e;
}
Dataspace.stack = oldStack;
return result;
};
Dataspace.wrap = function (f) {
var savedStack = Dataspace.stack;
return function () {
var actuals = arguments;
return Dataspace.withDataspaceStack(savedStack, function () {
var result = Dataspace.current().asChild(Dataspace.activePid(), function () {
return f.apply(null, actuals);
});
Dataspace.stack.reverse().forEach(function (entry) {
entry.dataspace.markRunnable(entry.activePid);
});
return result;
});
};
};
Dataspace.enqueueAction = function (action) {
var entry = Dataspace.stack.last();
entry.dataspace.enqueueAction(entry.activePid, action);
};
Dataspace.send = function (body, metaLevel) {
Dataspace.enqueueAction(message(Patch.prependAtMeta(body, metaLevel || 0)));
};
Dataspace.stateChange = function (patch) {
Dataspace.enqueueAction(stateChange(patch));
};
Dataspace.spawn = function (behavior) {
Dataspace.enqueueAction(spawn(behavior));
};
Dataspace.exit = function (exn) {
Dataspace.current().kill(Dataspace.activePid(), exn);
};
Dataspace.exitDataspace = function () {
Dataspace.enqueueAction(terminateDataspace());
};
Dataspace.inertBehavior = {
handleEvent: function (e) {}
};
// Instance methods
Dataspace.prototype.asChild = function (pid, f, omitLivenessCheck) {
var self = this;
var p = this.processTable.get(pid, null);
if (!omitLivenessCheck && (p === null)) {
console.warn("Dataspace.asChild eliding invocation of dead process", pid);
return;
}
return Dataspace.withDataspaceStack(
Dataspace.stack.push({ dataspace: this, activePid: pid }),
function () {
try {
return f(p);
} catch (e) {
self.kill(pid, e);
}
});
};
Dataspace.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: Dataspace.inertBehavior });
if (p) {
if (p.behavior.trapexit) {
this.asChild(pid, function () { return p.behavior.trapexit(exn); }, true);
}
this.enqueueAction(pid, terminate());
}
};
Dataspace.prototype.boot = function () {
// Needed in order for a new Dataspace to be marked as "runnable", so
// its initial actions get performed.
};
Dataspace.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;
};
Dataspace.prototype.step = function () {
return this.dispatchActions()
&& this.runRunnablePids()
&& ((this.pendingActions.size > 0) || (this.runnablePids.size > 0));
};
Dataspace.prototype.enqueueAction = function (pid, action) {
this.pendingActions = this.pendingActions.push([pid, action]);
};
Dataspace.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;
};
Dataspace.prototype.markRunnable = function (pid) {
this.runnablePids = this.runnablePids.add(pid);
};
Dataspace.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;
};
Dataspace.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)) {
Dataspace.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 'terminateDataspace':
Dataspace.exit();
return false;
default:
var exn = new Error("Action type " + action.type + " not understood");
exn.action = action;
throw exn;
}
};
Dataspace.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(Dataspace.stateChange);
this.onStateChange(this.mux, updateStreamResult.deltaAggregate);
};
Dataspace.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.terminateDataspace = terminateDataspace;
module.exports.Dataspace = Dataspace;
},{"./mux.js":229,"./patch.js":230,"./route.js":233,"immutable":220}],224:[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}],225:[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 Dataspace_ = require("./dataspace.js");
var Dataspace = Dataspace_.Dataspace;
var __ = Dataspace_.__;
var _$ = Dataspace_._$;
function spawnDOMDriver(domWrapFunction, jQueryWrapFunction) {
domWrapFunction = domWrapFunction || defaultWrapFunction;
var spec = domWrapFunction(_$('selector'), _$('fragmentClass'), _$('fragmentSpec'));
Dataspace.spawn(
new DemandMatcher(spec,
Patch.advertise(spec),
{
onDemandIncrease: function (c) {
Dataspace.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);
Dataspace.spawn(new Dataspace(function () {
Syndicate.JQuery.spawnJQueryDriver(self.selector+" > ."+self.fragmentClass,
1,
self.jQueryWrapFunction);
Dataspace.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) {
Dataspace.exitDataspace();
}
}
});
}));
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);
}
Dataspace.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,"./dataspace.js":223,"./demand-matcher.js":224,"./patch.js":230,"./seal.js":234}],226:[function(require,module,exports){
"use strict";
var Immutable = require('immutable');
var Dataspace = require('./dataspace.js').Dataspace;
function Ground(bootFn) {
var self = this;
this.stepperId = null;
this.baseStack = Immutable.List.of({ dataspace: this, activePid: -1 });
Dataspace.withDataspaceStack(this.baseStack, function () {
self.dataspace = new Dataspace(bootFn);
});
}
Ground.prototype.step = function () {
var self = this;
return Dataspace.withDataspaceStack(this.baseStack, function () {
return self.dataspace.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 dataspace 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;
},{"./dataspace.js":223,"immutable":220}],227:[function(require,module,exports){
// JQuery event driver
var Patch = require("./patch.js");
var DemandMatcher = require('./demand-matcher.js').DemandMatcher;
var Dataspace_ = require("./dataspace.js");
var Dataspace = Dataspace_.Dataspace;
var __ = Dataspace_.__;
var _$ = Dataspace_._$;
function spawnJQueryDriver(baseSelector, metaLevel, wrapFunction) {
metaLevel = metaLevel || 0;
wrapFunction = wrapFunction || defaultWrapFunction;
Dataspace.spawn(
new DemandMatcher(Patch.observe(wrapFunction(_$('selector'), _$('eventName'), __)),
Patch.advertise(wrapFunction(_$('selector'), _$('eventName'), __)),
{
metaLevel: metaLevel,
onDemandIncrease: function (c) {
Dataspace.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 =
Dataspace.wrap(function (e) {
Dataspace.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);
Dataspace.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;
},{"./dataspace.js":223,"./demand-matcher.js":224,"./patch.js":230}],228:[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("./dataspace.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,"./dataspace.js":223,"./demand-matcher.js":224,"./dom-driver.js":225,"./ground.js":226,"./jquery-driver.js":227,"./patch.js":230,"./randomid.js":231,"./reflect.js":232,"./route.js":233,"./seal.js":234}],229:[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}],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}]},{},[228])(228)
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlL2VtcHR5LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWIvYjY0LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2lzYXJyYXkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9hZXMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9hdXRoQ2lwaGVyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2RlY3J5cHRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2VuY3J5cHRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2doYXNoLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jYmMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jZmIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jZmIxLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2ZiOC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL2N0ci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL2VjYi5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL29mYi5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL25vZGVfbW9kdWxlcy9idWZmZXIteG9yL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbm9kZV9tb2R1bGVzL2NpcGhlci1iYXNlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvc3RyZWFtQ2lwaGVyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1kZXMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWRlcy9tb2Rlcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktZGVzL25vZGVfbW9kdWxlcy9jaXBoZXItYmFzZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktZGVzL25vZGVfbW9kdWxlcy9kZXMuanMvbGliL2Rlcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktZGVzL25vZGVfbW9kdWxlcy9kZXMuanMvbGliL2Rlcy9jYmMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWRlcy9ub2RlX21vZHVsZXMvZGVzLmpzL2xpYi9kZXMvY2lwaGVyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1kZXMvbm9kZV9tb2R1bGVzL2Rlcy5qcy9saWIvZGVzL2Rlcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1jaXBoZXIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktZGVzL25vZGVfbW9kdWxlcy9kZXMuanMvbGliL2Rlcy9lZGUuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWRlcy9ub2RlX21vZHVsZXMvZGVzLmpzL2xpYi9kZXMvdXRpbHMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktY2lwaGVyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWRlcy9ub2RlX21vZHVsZXMvZGVzLmpzL25vZGVfbW9kdWxlcy9taW5pbWFsaXN0aWMtYXNzZXJ0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9ub2RlX21vZHVsZXMvZXZwX2J5dGVzdG9rZXkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9hbGdvcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9jdXJ2ZXMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvYm4uanMvbGliL2JuLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktcnNhL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvY3VydmUvYmFzZS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvY3VydmUvZWR3YXJkcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvY3VydmUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2N1cnZlL21vbnQuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2N1cnZlL3Nob3J0LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9jdXJ2ZXMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2VjL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9lYy9rZXkuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2VjL3NpZ25hdHVyZS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvZWRkc2EvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2VkZHNhL2tleS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvZWRkc2Evc2lnbmF0dXJlLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9obWFjLWRyYmcuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL3ByZWNvbXB1dGVkL3NlY3AyNTZrMS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvdXRpbHMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbm9kZV9tb2R1bGVzL2Jyb3JhbmQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2guanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvY29tbW9uLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL2htYWMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvZWxsaXB0aWMvbm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvcmlwZW1kLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL2VsbGlwdGljL25vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9ub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC91dGlscy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9lbGxpcHRpYy9wYWNrYWdlLmpzb24iLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9hZXNpZC5qc29uIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvYXNuMS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL2ZpeFByb2MuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvYXBpLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvYmFzZS9idWZmZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9iYXNlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvYmFzZS9ub2RlLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvYmFzZS9yZXBvcnRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2NvbnN0YW50cy9kZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9jb25zdGFudHMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9kZWNvZGVycy9kZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9kZWNvZGVycy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2RlY29kZXJzL3BlbS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2VuY29kZXJzL2Rlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2VuY29kZXJzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvZW5jb2RlcnMvcGVtLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2Flcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9hdXRoQ2lwaGVyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2RlY3J5cHRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9lbmNyeXB0ZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvZ2hhc2guanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2ZiLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL2NmYjEuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2ZiOC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jdHIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvb2ZiLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL25vZGVfbW9kdWxlcy9idWZmZXIteG9yL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL25vZGVfbW9kdWxlcy9jaXBoZXItYmFzZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9zdHJlYW1DaXBoZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvZXZwX2J5dGVzdG9rZXkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9zaWduLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vdmVyaWZ5LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtZWNkaC9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9oZWxwZXJzLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9tZDUuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL25vZGVfbW9kdWxlcy9jaXBoZXItYmFzZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3JlYXRlLWhhc2gvbm9kZV9tb2R1bGVzL3JpcGVtZDE2MC9saWIvcmlwZW1kMTYwLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9ub2RlX21vZHVsZXMvc2hhLmpzL2hhc2guanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL25vZGVfbW9kdWxlcy9zaGEuanMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL25vZGVfbW9kdWxlcy9zaGEuanMvc2hhLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9ub2RlX21vZHVsZXMvc2hhLmpzL3NoYTEuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL25vZGVfbW9kdWxlcy9zaGEuanMvc2hhMjI0LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9ub2RlX21vZHVsZXMvc2hhLmpzL3NoYTI1Ni5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3JlYXRlLWhhc2gvbm9kZV9tb2R1bGVzL3NoYS5qcy9zaGEzODQuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL25vZGVfbW9kdWxlcy9zaGEuanMvc2hhNTEyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcmVhdGUtaG1hYy9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9kaWZmaWUtaGVsbG1hbi9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9kaWZmaWUtaGVsbG1hbi9saWIvZGguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2RpZmZpZS1oZWxsbWFuL2xpYi9nZW5lcmF0ZVByaW1lLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9kaWZmaWUtaGVsbG1hbi9saWIvcHJpbWVzLmpzb24iLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2RpZmZpZS1oZWxsbWFuL25vZGVfbW9kdWxlcy9taWxsZXItcmFiaW4vbGliL21yLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wYmtkZjIvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbWdmLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1yc2EvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL2ZpeFByb2MuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvYWVzLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvYXV0aENpcGhlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2RlY3J5cHRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2VuY3J5cHRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2doYXNoLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2ZiLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9ub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2ZiMS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL2NmYjguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jdHIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9vZmIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L25vZGVfbW9kdWxlcy9wYXJzZS1hc24xL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9ub2RlX21vZHVsZXMvYnVmZmVyLXhvci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL25vZGVfbW9kdWxlcy9jaXBoZXItYmFzZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL3N0cmVhbUNpcGhlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvbm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvbm9kZV9tb2R1bGVzL2V2cF9ieXRlc3Rva2V5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9wcml2YXRlRGVjcnlwdC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvcHVibGljRW5jcnlwdC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvd2l0aFB1YmxpYy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQveG9yLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NyeXB0by1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yYW5kb21ieXRlcy9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2V2ZW50cy9ldmVudHMuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9pbnNlcnQtbW9kdWxlLWdsb2JhbHMvbm9kZV9tb2R1bGVzL2lzLWJ1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9pc2FycmF5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vZHVwbGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9kdXBsZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3Bhc3N0aHJvdWdoLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9yZWFkYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV93cml0YWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbm9kZV9tb2R1bGVzL2NvcmUtdXRpbC1pcy9saWIvdXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbm9kZV9tb2R1bGVzL3Byb2Nlc3MtbmV4dGljay1hcmdzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9ub2RlX21vZHVsZXMvdXRpbC1kZXByZWNhdGUvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vcGFzc3Rocm91Z2guanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS90cmFuc2Zvcm0uanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3dyaXRhYmxlLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3ZtLWJyb3dzZXJpZnkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvdm0tYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvaW5kZXhvZi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9pbW11dGFibGUvZGlzdC9pbW11dGFibGUuanMiLCJzcmMvYWNrLmpzIiwic3JjL2FjdG9yLmpzIiwic3JjL2RhdGFzcGFjZS5qcyIsInNyYy9kZW1hbmQtbWF0Y2hlci5qcyIsInNyYy9kb20tZHJpdmVyLmpzIiwic3JjL2dyb3VuZC5qcyIsInNyYy9qcXVlcnktZHJpdmVyLmpzIiwic3JjL21haW4uanMiLCJzcmMvbXV4LmpzIiwic3JjL3BhdGNoLmpzIiwic3JjL3JhbmRvbWlkLmpzIiwic3JjL3JlZmxlY3QuanMiLCJzcmMvcm91dGUuanMiLCJzcmMvc2VhbC5qcyIsInNyYy91dGlsLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7OztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzk2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNqTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN6SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzFIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNsR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0tBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDMUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzFGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0lBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDcEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3hFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDdkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3IwR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNzRCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNXdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0tBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3JIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUM5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDckdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xtQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xVQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2pMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDakdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN6SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzFIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7OztBQ2xHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDMUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNwRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3pMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3ZHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUMxSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUMzSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDMUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2xOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3JFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNwR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDaEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDcERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzdJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMxUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDcEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDakhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNyR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDakxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNqR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3pJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDMUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7O0FDbEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMxRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDM0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDOUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMVNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNGQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMvOEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDamhCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDM0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ25FQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7O0FDREE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9IQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3IzSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM1NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDelFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3bENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIiIsIi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG5cbid1c2Ugc3RyaWN0J1xuXG52YXIgYmFzZTY0ID0gcmVxdWlyZSgnYmFzZTY0LWpzJylcbnZhciBpZWVlNzU0ID0gcmVxdWlyZSgnaWVlZTc1NCcpXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gU2xvd0J1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxudmFyIHJvb3RQYXJlbnQgPSB7fVxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBEdWUgdG8gdmFyaW91cyBicm93c2VyIGJ1Z3MsIHNvbWV0aW1lcyB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uIHdpbGwgYmUgdXNlZCBldmVuXG4gKiB3aGVuIHRoZSBicm93c2VyIHN1cHBvcnRzIHR5cGVkIGFycmF5cy5cbiAqXG4gKiBOb3RlOlxuICpcbiAqICAgLSBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMsXG4gKiAgICAgU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzguXG4gKlxuICogICAtIENocm9tZSA5LTEwIGlzIG1pc3NpbmcgdGhlIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24uXG4gKlxuICogICAtIElFMTAgaGFzIGEgYnJva2VuIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhcnJheXMgb2ZcbiAqICAgICBpbmNvcnJlY3QgbGVuZ3RoIGluIHNvbWUgc2l0dWF0aW9ucy5cblxuICogV2UgZGV0ZWN0IHRoZXNlIGJ1Z2d5IGJyb3dzZXJzIGFuZCBzZXQgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYCB0byBgZmFsc2VgIHNvIHRoZXlcbiAqIGdldCB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyBzbG93ZXIgYnV0IGJlaGF2ZXMgY29ycmVjdGx5LlxuICovXG5CdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCA9IGdsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUICE9PSB1bmRlZmluZWRcbiAgPyBnbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVFxuICA6IHR5cGVkQXJyYXlTdXBwb3J0KClcblxuZnVuY3Rpb24gdHlwZWRBcnJheVN1cHBvcnQgKCkge1xuICB0cnkge1xuICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheSgxKVxuICAgIGFyci5mb28gPSBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9XG4gICAgcmV0dXJuIGFyci5mb28oKSA9PT0gNDIgJiYgLy8gdHlwZWQgYXJyYXkgaW5zdGFuY2VzIGNhbiBiZSBhdWdtZW50ZWRcbiAgICAgICAgdHlwZW9mIGFyci5zdWJhcnJheSA9PT0gJ2Z1bmN0aW9uJyAmJiAvLyBjaHJvbWUgOS0xMCBsYWNrIGBzdWJhcnJheWBcbiAgICAgICAgYXJyLnN1YmFycmF5KDEsIDEpLmJ5dGVMZW5ndGggPT09IDAgLy8gaWUxMCBoYXMgYnJva2VuIGBzdWJhcnJheWBcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbmZ1bmN0aW9uIGtNYXhMZW5ndGggKCkge1xuICByZXR1cm4gQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRcbiAgICA/IDB4N2ZmZmZmZmZcbiAgICA6IDB4M2ZmZmZmZmZcbn1cblxuLyoqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGhhdmUgdGhlaXJcbiAqIHByb3RvdHlwZSBjaGFuZ2VkIHRvIGBCdWZmZXIucHJvdG90eXBlYC4gRnVydGhlcm1vcmUsIGBCdWZmZXJgIGlzIGEgc3ViY2xhc3Mgb2ZcbiAqIGBVaW50OEFycmF5YCwgc28gdGhlIHJldHVybmVkIGluc3RhbmNlcyB3aWxsIGhhdmUgYWxsIHRoZSBub2RlIGBCdWZmZXJgIG1ldGhvZHNcbiAqIGFuZCB0aGUgYFVpbnQ4QXJyYXlgIG1ldGhvZHMuIFNxdWFyZSBicmFja2V0IG5vdGF0aW9uIHdvcmtzIGFzIGV4cGVjdGVkIC0tIGl0XG4gKiByZXR1cm5zIGEgc2luZ2xlIG9jdGV0LlxuICpcbiAqIFRoZSBgVWludDhBcnJheWAgcHJvdG90eXBlIHJlbWFpbnMgdW5tb2RpZmllZC5cbiAqL1xuZnVuY3Rpb24gQnVmZmVyIChhcmcpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpIHtcbiAgICAvLyBBdm9pZCBnb2luZyB0aHJvdWdoIGFuIEFyZ3VtZW50c0FkYXB0b3JUcmFtcG9saW5lIGluIHRoZSBjb21tb24gY2FzZS5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHJldHVybiBuZXcgQnVmZmVyKGFyZywgYXJndW1lbnRzWzFdKVxuICAgIHJldHVybiBuZXcgQnVmZmVyKGFyZylcbiAgfVxuXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzLmxlbmd0aCA9IDBcbiAgICB0aGlzLnBhcmVudCA9IHVuZGVmaW5lZFxuICB9XG5cbiAgLy8gQ29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIHJldHVybiBmcm9tTnVtYmVyKHRoaXMsIGFyZylcbiAgfVxuXG4gIC8vIFNsaWdodGx5IGxlc3MgY29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmcm9tU3RyaW5nKHRoaXMsIGFyZywgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiAndXRmOCcpXG4gIH1cblxuICAvLyBVbnVzdWFsLlxuICByZXR1cm4gZnJvbU9iamVjdCh0aGlzLCBhcmcpXG59XG5cbi8vIFRPRE86IExlZ2FjeSwgbm90IG5lZWRlZCBhbnltb3JlLiBSZW1vdmUgaW4gbmV4dCBtYWpvciB2ZXJzaW9uLlxuQnVmZmVyLl9hdWdtZW50ID0gZnVuY3Rpb24gKGFycikge1xuICBhcnIuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICByZXR1cm4gYXJyXG59XG5cbmZ1bmN0aW9uIGZyb21OdW1iZXIgKHRoYXQsIGxlbmd0aCkge1xuICB0aGF0ID0gYWxsb2NhdGUodGhhdCwgbGVuZ3RoIDwgMCA/IDAgOiBjaGVja2VkKGxlbmd0aCkgfCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgdGhhdFtpXSA9IDBcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbVN0cmluZyAodGhhdCwgc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJyB8fCBlbmNvZGluZyA9PT0gJycpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgLy8gQXNzdW1wdGlvbjogYnl0ZUxlbmd0aCgpIHJldHVybiB2YWx1ZSBpcyBhbHdheXMgPCBrTWF4TGVuZ3RoLlxuICB2YXIgbGVuZ3RoID0gYnl0ZUxlbmd0aChzdHJpbmcsIGVuY29kaW5nKSB8IDBcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcblxuICB0aGF0LndyaXRlKHN0cmluZywgZW5jb2RpbmcpXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21PYmplY3QgKHRoYXQsIG9iamVjdCkge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKG9iamVjdCkpIHJldHVybiBmcm9tQnVmZmVyKHRoYXQsIG9iamVjdClcblxuICBpZiAoaXNBcnJheShvYmplY3QpKSByZXR1cm4gZnJvbUFycmF5KHRoYXQsIG9iamVjdClcblxuICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdtdXN0IHN0YXJ0IHdpdGggbnVtYmVyLCBidWZmZXIsIGFycmF5IG9yIHN0cmluZycpXG4gIH1cblxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJykge1xuICAgIGlmIChvYmplY3QuYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgIHJldHVybiBmcm9tVHlwZWRBcnJheSh0aGF0LCBvYmplY3QpXG4gICAgfVxuICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgICAgcmV0dXJuIGZyb21BcnJheUJ1ZmZlcih0aGF0LCBvYmplY3QpXG4gICAgfVxuICB9XG5cbiAgaWYgKG9iamVjdC5sZW5ndGgpIHJldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsIG9iamVjdClcblxuICByZXR1cm4gZnJvbUpzb25PYmplY3QodGhhdCwgb2JqZWN0KVxufVxuXG5mdW5jdGlvbiBmcm9tQnVmZmVyICh0aGF0LCBidWZmZXIpIHtcbiAgdmFyIGxlbmd0aCA9IGNoZWNrZWQoYnVmZmVyLmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIGJ1ZmZlci5jb3B5KHRoYXQsIDAsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5ICh0aGF0LCBhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gY2hlY2tlZChhcnJheS5sZW5ndGgpIHwgMFxuICB0aGF0ID0gYWxsb2NhdGUodGhhdCwgbGVuZ3RoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuLy8gRHVwbGljYXRlIG9mIGZyb21BcnJheSgpIHRvIGtlZXAgZnJvbUFycmF5KCkgbW9ub21vcnBoaWMuXG5mdW5jdGlvbiBmcm9tVHlwZWRBcnJheSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcbiAgLy8gVHJ1bmNhdGluZyB0aGUgZWxlbWVudHMgaXMgcHJvYmFibHkgbm90IHdoYXQgcGVvcGxlIGV4cGVjdCBmcm9tIHR5cGVkXG4gIC8vIGFycmF5cyB3aXRoIEJZVEVTX1BFUl9FTEVNRU5UID4gMSBidXQgaXQncyBjb21wYXRpYmxlIHdpdGggdGhlIGJlaGF2aW9yXG4gIC8vIG9mIHRoZSBvbGQgQnVmZmVyIGNvbnN0cnVjdG9yLlxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5QnVmZmVyICh0aGF0LCBhcnJheSkge1xuICBhcnJheS5ieXRlTGVuZ3RoIC8vIHRoaXMgdGhyb3dzIGlmIGBhcnJheWAgaXMgbm90IGEgdmFsaWQgQXJyYXlCdWZmZXJcblxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXkpXG4gICAgdGhhdC5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIHRoYXQgPSBmcm9tVHlwZWRBcnJheSh0aGF0LCBuZXcgVWludDhBcnJheShhcnJheSkpXG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5TGlrZSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8vIERlc2VyaWFsaXplIHsgdHlwZTogJ0J1ZmZlcicsIGRhdGE6IFsxLDIsMywuLi5dIH0gaW50byBhIEJ1ZmZlciBvYmplY3QuXG4vLyBSZXR1cm5zIGEgemVyby1sZW5ndGggYnVmZmVyIGZvciBpbnB1dHMgdGhhdCBkb24ndCBjb25mb3JtIHRvIHRoZSBzcGVjLlxuZnVuY3Rpb24gZnJvbUpzb25PYmplY3QgKHRoYXQsIG9iamVjdCkge1xuICB2YXIgYXJyYXlcbiAgdmFyIGxlbmd0aCA9IDBcblxuICBpZiAob2JqZWN0LnR5cGUgPT09ICdCdWZmZXInICYmIGlzQXJyYXkob2JqZWN0LmRhdGEpKSB7XG4gICAgYXJyYXkgPSBvYmplY3QuZGF0YVxuICAgIGxlbmd0aCA9IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgfVxuICB0aGF0ID0gYWxsb2NhdGUodGhhdCwgbGVuZ3RoKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGF0W2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG5pZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgQnVmZmVyLnByb3RvdHlwZS5fX3Byb3RvX18gPSBVaW50OEFycmF5LnByb3RvdHlwZVxuICBCdWZmZXIuX19wcm90b19fID0gVWludDhBcnJheVxufSBlbHNlIHtcbiAgLy8gcHJlLXNldCBmb3IgdmFsdWVzIHRoYXQgbWF5IGV4aXN0IGluIHRoZSBmdXR1cmVcbiAgQnVmZmVyLnByb3RvdHlwZS5sZW5ndGggPSB1bmRlZmluZWRcbiAgQnVmZmVyLnByb3RvdHlwZS5wYXJlbnQgPSB1bmRlZmluZWRcbn1cblxuZnVuY3Rpb24gYWxsb2NhdGUgKHRoYXQsIGxlbmd0aCkge1xuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gbmV3IFVpbnQ4QXJyYXkobGVuZ3RoKVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0Lmxlbmd0aCA9IGxlbmd0aFxuICB9XG5cbiAgdmFyIGZyb21Qb29sID0gbGVuZ3RoICE9PSAwICYmIGxlbmd0aCA8PSBCdWZmZXIucG9vbFNpemUgPj4+IDFcbiAgaWYgKGZyb21Qb29sKSB0aGF0LnBhcmVudCA9IHJvb3RQYXJlbnRcblxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBjaGVja2VkIChsZW5ndGgpIHtcbiAgLy8gTm90ZTogY2Fubm90IHVzZSBgbGVuZ3RoIDwga01heExlbmd0aGAgaGVyZSBiZWNhdXNlIHRoYXQgZmFpbHMgd2hlblxuICAvLyBsZW5ndGggaXMgTmFOICh3aGljaCBpcyBvdGhlcndpc2UgY29lcmNlZCB0byB6ZXJvLilcbiAgaWYgKGxlbmd0aCA+PSBrTWF4TGVuZ3RoKCkpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byBhbGxvY2F0ZSBCdWZmZXIgbGFyZ2VyIHRoYW4gbWF4aW11bSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAnc2l6ZTogMHgnICsga01heExlbmd0aCgpLnRvU3RyaW5nKDE2KSArICcgYnl0ZXMnKVxuICB9XG4gIHJldHVybiBsZW5ndGggfCAwXG59XG5cbmZ1bmN0aW9uIFNsb3dCdWZmZXIgKHN1YmplY3QsIGVuY29kaW5nKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTbG93QnVmZmVyKSkgcmV0dXJuIG5ldyBTbG93QnVmZmVyKHN1YmplY3QsIGVuY29kaW5nKVxuXG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKHN1YmplY3QsIGVuY29kaW5nKVxuICBkZWxldGUgYnVmLnBhcmVudFxuICByZXR1cm4gYnVmXG59XG5cbkJ1ZmZlci5pc0J1ZmZlciA9IGZ1bmN0aW9uIGlzQnVmZmVyIChiKSB7XG4gIHJldHVybiAhIShiICE9IG51bGwgJiYgYi5faXNCdWZmZXIpXG59XG5cbkJ1ZmZlci5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAoYSwgYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihhKSB8fCAhQnVmZmVyLmlzQnVmZmVyKGIpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnRzIG11c3QgYmUgQnVmZmVycycpXG4gIH1cblxuICBpZiAoYSA9PT0gYikgcmV0dXJuIDBcblxuICB2YXIgeCA9IGEubGVuZ3RoXG4gIHZhciB5ID0gYi5sZW5ndGhcblxuICB2YXIgaSA9IDBcbiAgdmFyIGxlbiA9IE1hdGgubWluKHgsIHkpXG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIGJyZWFrXG5cbiAgICArK2lcbiAgfVxuXG4gIGlmIChpICE9PSBsZW4pIHtcbiAgICB4ID0gYVtpXVxuICAgIHkgPSBiW2ldXG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24gaXNFbmNvZGluZyAoZW5jb2RpbmcpIHtcbiAgc3dpdGNoIChTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgIGNhc2UgJ3Jhdyc6XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldHVybiB0cnVlXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbkJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbiBjb25jYXQgKGxpc3QsIGxlbmd0aCkge1xuICBpZiAoIWlzQXJyYXkobGlzdCkpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2xpc3QgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzLicpXG5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoMClcbiAgfVxuXG4gIHZhciBpXG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGxlbmd0aCA9IDBcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgbGVuZ3RoICs9IGxpc3RbaV0ubGVuZ3RoXG4gICAgfVxuICB9XG5cbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuICB2YXIgcG9zID0gMFxuICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgIHZhciBpdGVtID0gbGlzdFtpXVxuICAgIGl0ZW0uY29weShidWYsIHBvcylcbiAgICBwb3MgKz0gaXRlbS5sZW5ndGhcbiAgfVxuICByZXR1cm4gYnVmXG59XG5cbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSBzdHJpbmcgPSAnJyArIHN0cmluZ1xuXG4gIHZhciBsZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGlmIChsZW4gPT09IDApIHJldHVybiAwXG5cbiAgLy8gVXNlIGEgZm9yIGxvb3AgdG8gYXZvaWQgcmVjdXJzaW9uXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgLy8gRGVwcmVjYXRlZFxuICAgICAgY2FzZSAncmF3JzpcbiAgICAgIGNhc2UgJ3Jhd3MnOlxuICAgICAgICByZXR1cm4gbGVuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gbGVuICogMlxuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGxlbiA+Pj4gMVxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoIC8vIGFzc3VtZSB1dGY4XG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcblxuZnVuY3Rpb24gc2xvd1RvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuXG4gIHN0YXJ0ID0gc3RhcnQgfCAwXG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA9PT0gSW5maW5pdHkgPyB0aGlzLmxlbmd0aCA6IGVuZCB8IDBcblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAoZW5kIDw9IHN0YXJ0KSByZXR1cm4gJydcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBiaW5hcnlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHV0ZjE2bGVTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuLy8gVGhlIHByb3BlcnR5IGlzIHVzZWQgYnkgYEJ1ZmZlci5pc0J1ZmZlcmAgYW5kIGBpcy1idWZmZXJgIChpbiBTYWZhcmkgNS03KSB0byBkZXRlY3Rcbi8vIEJ1ZmZlciBpbnN0YW5jZXMuXG5CdWZmZXIucHJvdG90eXBlLl9pc0J1ZmZlciA9IHRydWVcblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoIHwgMFxuICBpZiAobGVuZ3RoID09PSAwKSByZXR1cm4gJydcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHJldHVybiB1dGY4U2xpY2UodGhpcywgMCwgbGVuZ3RoKVxuICByZXR1cm4gc2xvd1RvU3RyaW5nLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIHRydWVcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpID09PSAwXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QgKCkge1xuICB2YXIgc3RyID0gJydcbiAgdmFyIG1heCA9IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVNcbiAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgIHN0ciA9IHRoaXMudG9TdHJpbmcoJ2hleCcsIDAsIG1heCkubWF0Y2goLy57Mn0vZykuam9pbignICcpXG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbWF4KSBzdHIgKz0gJyAuLi4gJ1xuICB9XG4gIHJldHVybiAnPEJ1ZmZlciAnICsgc3RyICsgJz4nXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIDBcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uIGluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCkge1xuICBpZiAoYnl0ZU9mZnNldCA+IDB4N2ZmZmZmZmYpIGJ5dGVPZmZzZXQgPSAweDdmZmZmZmZmXG4gIGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAtMHg4MDAwMDAwMCkgYnl0ZU9mZnNldCA9IC0weDgwMDAwMDAwXG4gIGJ5dGVPZmZzZXQgPj49IDBcblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybiAtMVxuICBpZiAoYnl0ZU9mZnNldCA+PSB0aGlzLmxlbmd0aCkgcmV0dXJuIC0xXG5cbiAgLy8gTmVnYXRpdmUgb2Zmc2V0cyBzdGFydCBmcm9tIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlclxuICBpZiAoYnl0ZU9mZnNldCA8IDApIGJ5dGVPZmZzZXQgPSBNYXRoLm1heCh0aGlzLmxlbmd0aCArIGJ5dGVPZmZzZXQsIDApXG5cbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDApIHJldHVybiAtMSAvLyBzcGVjaWFsIGNhc2U6IGxvb2tpbmcgZm9yIGVtcHR5IHN0cmluZyBhbHdheXMgZmFpbHNcbiAgICByZXR1cm4gU3RyaW5nLnByb3RvdHlwZS5pbmRleE9mLmNhbGwodGhpcywgdmFsLCBieXRlT2Zmc2V0KVxuICB9XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsKSkge1xuICAgIHJldHVybiBhcnJheUluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0KVxuICB9XG4gIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZih0aGlzLCBbIHZhbCBdLCBieXRlT2Zmc2V0KVxuICB9XG5cbiAgZnVuY3Rpb24gYXJyYXlJbmRleE9mIChhcnIsIHZhbCwgYnl0ZU9mZnNldCkge1xuICAgIHZhciBmb3VuZEluZGV4ID0gLTFcbiAgICBmb3IgKHZhciBpID0gMDsgYnl0ZU9mZnNldCArIGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChhcnJbYnl0ZU9mZnNldCArIGldID09PSB2YWxbZm91bmRJbmRleCA9PT0gLTEgPyAwIDogaSAtIGZvdW5kSW5kZXhdKSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ID09PSAtMSkgZm91bmRJbmRleCA9IGlcbiAgICAgICAgaWYgKGkgLSBmb3VuZEluZGV4ICsgMSA9PT0gdmFsLmxlbmd0aCkgcmV0dXJuIGJ5dGVPZmZzZXQgKyBmb3VuZEluZGV4XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3VuZEluZGV4ID0gLTFcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xXG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCd2YWwgbXVzdCBiZSBzdHJpbmcsIG51bWJlciBvciBCdWZmZXInKVxufVxuXG5mdW5jdGlvbiBoZXhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIG9mZnNldCA9IE51bWJlcihvZmZzZXQpIHx8IDBcbiAgdmFyIHJlbWFpbmluZyA9IGJ1Zi5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSBOdW1iZXIobGVuZ3RoKVxuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICAgIH1cbiAgfVxuXG4gIC8vIG11c3QgYmUgYW4gZXZlbiBudW1iZXIgb2YgZGlnaXRzXG4gIHZhciBzdHJMZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGlmIChzdHJMZW4gJSAyICE9PSAwKSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaGV4IHN0cmluZycpXG5cbiAgaWYgKGxlbmd0aCA+IHN0ckxlbiAvIDIpIHtcbiAgICBsZW5ndGggPSBzdHJMZW4gLyAyXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJzZWQgPSBwYXJzZUludChzdHJpbmcuc3Vic3RyKGkgKiAyLCAyKSwgMTYpXG4gICAgaWYgKGlzTmFOKHBhcnNlZCkpIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJylcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSBwYXJzZWRcbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiB1dGY4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBhc2NpaVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGJpbmFyeVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGFzY2lpV3JpdGUoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBiYXNlNjRXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGJhc2U2NFRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gdWNzMldyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmMTZsZVRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIHdyaXRlIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nKVxuICBpZiAob2Zmc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBlbmNvZGluZylcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIG9mZnNldFssIGxlbmd0aF1bLCBlbmNvZGluZ10pXG4gIH0gZWxzZSBpZiAoaXNGaW5pdGUob2Zmc2V0KSkge1xuICAgIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgICBpZiAoaXNGaW5pdGUobGVuZ3RoKSkge1xuICAgICAgbGVuZ3RoID0gbGVuZ3RoIHwgMFxuICAgICAgaWYgKGVuY29kaW5nID09PSB1bmRlZmluZWQpIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgfSBlbHNlIHtcbiAgICAgIGVuY29kaW5nID0gbGVuZ3RoXG4gICAgICBsZW5ndGggPSB1bmRlZmluZWRcbiAgICB9XG4gIC8vIGxlZ2FjeSB3cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXQsIGxlbmd0aCkgLSByZW1vdmUgaW4gdjAuMTNcbiAgfSBlbHNlIHtcbiAgICB2YXIgc3dhcCA9IGVuY29kaW5nXG4gICAgZW5jb2RpbmcgPSBvZmZzZXRcbiAgICBvZmZzZXQgPSBsZW5ndGggfCAwXG4gICAgbGVuZ3RoID0gc3dhcFxuICB9XG5cbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCB8fCBsZW5ndGggPiByZW1haW5pbmcpIGxlbmd0aCA9IHJlbWFpbmluZ1xuXG4gIGlmICgoc3RyaW5nLmxlbmd0aCA+IDAgJiYgKGxlbmd0aCA8IDAgfHwgb2Zmc2V0IDwgMCkpIHx8IG9mZnNldCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2F0dGVtcHQgdG8gd3JpdGUgb3V0c2lkZSBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBiaW5hcnlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICAvLyBXYXJuaW5nOiBtYXhMZW5ndGggbm90IHRha2VuIGludG8gYWNjb3VudCBpbiBiYXNlNjRXcml0ZVxuICAgICAgICByZXR1cm4gYmFzZTY0V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHVjczJXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04gKCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6ICdCdWZmZXInLFxuICAgIGRhdGE6IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHRoaXMuX2FyciB8fCB0aGlzLCAwKVxuICB9XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKHN0YXJ0ID09PSAwICYmIGVuZCA9PT0gYnVmLmxlbmd0aCkge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zi5zbGljZShzdGFydCwgZW5kKSlcbiAgfVxufVxuXG5mdW5jdGlvbiB1dGY4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG4gIHZhciByZXMgPSBbXVxuXG4gIHZhciBpID0gc3RhcnRcbiAgd2hpbGUgKGkgPCBlbmQpIHtcbiAgICB2YXIgZmlyc3RCeXRlID0gYnVmW2ldXG4gICAgdmFyIGNvZGVQb2ludCA9IG51bGxcbiAgICB2YXIgYnl0ZXNQZXJTZXF1ZW5jZSA9IChmaXJzdEJ5dGUgPiAweEVGKSA/IDRcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4REYpID8gM1xuICAgICAgOiAoZmlyc3RCeXRlID4gMHhCRikgPyAyXG4gICAgICA6IDFcblxuICAgIGlmIChpICsgYnl0ZXNQZXJTZXF1ZW5jZSA8PSBlbmQpIHtcbiAgICAgIHZhciBzZWNvbmRCeXRlLCB0aGlyZEJ5dGUsIGZvdXJ0aEJ5dGUsIHRlbXBDb2RlUG9pbnRcblxuICAgICAgc3dpdGNoIChieXRlc1BlclNlcXVlbmNlKSB7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBpZiAoZmlyc3RCeXRlIDwgMHg4MCkge1xuICAgICAgICAgICAgY29kZVBvaW50ID0gZmlyc3RCeXRlXG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4MUYpIDw8IDB4NiB8IChzZWNvbmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3Rikge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweEMgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4NiB8ICh0aGlyZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGRiAmJiAodGVtcENvZGVQb2ludCA8IDB4RDgwMCB8fCB0ZW1wQ29kZVBvaW50ID4gMHhERkZGKSkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBmb3VydGhCeXRlID0gYnVmW2kgKyAzXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAoZm91cnRoQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHgxMiB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHhDIHwgKHRoaXJkQnl0ZSAmIDB4M0YpIDw8IDB4NiB8IChmb3VydGhCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHhGRkZGICYmIHRlbXBDb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjb2RlUG9pbnQgPT09IG51bGwpIHtcbiAgICAgIC8vIHdlIGRpZCBub3QgZ2VuZXJhdGUgYSB2YWxpZCBjb2RlUG9pbnQgc28gaW5zZXJ0IGFcbiAgICAgIC8vIHJlcGxhY2VtZW50IGNoYXIgKFUrRkZGRCkgYW5kIGFkdmFuY2Ugb25seSAxIGJ5dGVcbiAgICAgIGNvZGVQb2ludCA9IDB4RkZGRFxuICAgICAgYnl0ZXNQZXJTZXF1ZW5jZSA9IDFcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA+IDB4RkZGRikge1xuICAgICAgLy8gZW5jb2RlIHRvIHV0ZjE2IChzdXJyb2dhdGUgcGFpciBkYW5jZSlcbiAgICAgIGNvZGVQb2ludCAtPSAweDEwMDAwXG4gICAgICByZXMucHVzaChjb2RlUG9pbnQgPj4+IDEwICYgMHgzRkYgfCAweEQ4MDApXG4gICAgICBjb2RlUG9pbnQgPSAweERDMDAgfCBjb2RlUG9pbnQgJiAweDNGRlxuICAgIH1cblxuICAgIHJlcy5wdXNoKGNvZGVQb2ludClcbiAgICBpICs9IGJ5dGVzUGVyU2VxdWVuY2VcbiAgfVxuXG4gIHJldHVybiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkocmVzKVxufVxuXG4vLyBCYXNlZCBvbiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMjc0NzI3Mi82ODA3NDIsIHRoZSBicm93c2VyIHdpdGhcbi8vIHRoZSBsb3dlc3QgbGltaXQgaXMgQ2hyb21lLCB3aXRoIDB4MTAwMDAgYXJncy5cbi8vIFdlIGdvIDEgbWFnbml0dWRlIGxlc3MsIGZvciBzYWZldHlcbnZhciBNQVhfQVJHVU1FTlRTX0xFTkdUSCA9IDB4MTAwMFxuXG5mdW5jdGlvbiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkgKGNvZGVQb2ludHMpIHtcbiAgdmFyIGxlbiA9IGNvZGVQb2ludHMubGVuZ3RoXG4gIGlmIChsZW4gPD0gTUFYX0FSR1VNRU5UU19MRU5HVEgpIHtcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNvZGVQb2ludHMpIC8vIGF2b2lkIGV4dHJhIHNsaWNlKClcbiAgfVxuXG4gIC8vIERlY29kZSBpbiBjaHVua3MgdG8gYXZvaWQgXCJjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWRcIi5cbiAgdmFyIHJlcyA9ICcnXG4gIHZhciBpID0gMFxuICB3aGlsZSAoaSA8IGxlbikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFxuICAgICAgU3RyaW5nLFxuICAgICAgY29kZVBvaW50cy5zbGljZShpLCBpICs9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKVxuICAgIClcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldICYgMHg3RilcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGJpbmFyeVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGhleFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcblxuICBpZiAoIXN0YXJ0IHx8IHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmICghZW5kIHx8IGVuZCA8IDAgfHwgZW5kID4gbGVuKSBlbmQgPSBsZW5cblxuICB2YXIgb3V0ID0gJydcbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICBvdXQgKz0gdG9IZXgoYnVmW2ldKVxuICB9XG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGJ5dGVzID0gYnVmLnNsaWNlKHN0YXJ0LCBlbmQpXG4gIHZhciByZXMgPSAnJ1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0gKyBieXRlc1tpICsgMV0gKiAyNTYpXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24gc2xpY2UgKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIHN0YXJ0ID0gfn5zdGFydFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGxlbiA6IH5+ZW5kXG5cbiAgaWYgKHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ICs9IGxlblxuICAgIGlmIChzdGFydCA8IDApIHN0YXJ0ID0gMFxuICB9IGVsc2UgaWYgKHN0YXJ0ID4gbGVuKSB7XG4gICAgc3RhcnQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCAwKSB7XG4gICAgZW5kICs9IGxlblxuICAgIGlmIChlbmQgPCAwKSBlbmQgPSAwXG4gIH0gZWxzZSBpZiAoZW5kID4gbGVuKSB7XG4gICAgZW5kID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgdmFyIG5ld0J1ZlxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICBuZXdCdWYgPSB0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpXG4gICAgbmV3QnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICB2YXIgc2xpY2VMZW4gPSBlbmQgLSBzdGFydFxuICAgIG5ld0J1ZiA9IG5ldyBCdWZmZXIoc2xpY2VMZW4sIHVuZGVmaW5lZClcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNsaWNlTGVuOyBpKyspIHtcbiAgICAgIG5ld0J1ZltpXSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfVxuXG4gIGlmIChuZXdCdWYubGVuZ3RoKSBuZXdCdWYucGFyZW50ID0gdGhpcy5wYXJlbnQgfHwgdGhpc1xuXG4gIHJldHVybiBuZXdCdWZcbn1cblxuLypcbiAqIE5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgYnVmZmVyIGlzbid0IHRyeWluZyB0byB3cml0ZSBvdXQgb2YgYm91bmRzLlxuICovXG5mdW5jdGlvbiBjaGVja09mZnNldCAob2Zmc2V0LCBleHQsIGxlbmd0aCkge1xuICBpZiAoKG9mZnNldCAlIDEpICE9PSAwIHx8IG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdvZmZzZXQgaXMgbm90IHVpbnQnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gbGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVHJ5aW5nIHRvIGFjY2VzcyBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRMRSA9IGZ1bmN0aW9uIHJlYWRVSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRCRSA9IGZ1bmN0aW9uIHJlYWRVSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG4gIH1cblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdXG4gIHZhciBtdWwgPSAxXG4gIHdoaWxlIChieXRlTGVuZ3RoID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbiByZWFkVUludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2QkUgPSBmdW5jdGlvbiByZWFkVUludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgOCkgfCB0aGlzW29mZnNldCArIDFdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkxFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICgodGhpc1tvZmZzZXRdKSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikpICtcbiAgICAgICh0aGlzW29mZnNldCArIDNdICogMHgxMDAwMDAwKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdICogMHgxMDAwMDAwKSArXG4gICAgKCh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgIHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludExFID0gZnVuY3Rpb24gcmVhZEludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludEJFID0gZnVuY3Rpb24gcmVhZEludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoXG4gIHZhciBtdWwgPSAxXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0taV1cbiAgd2hpbGUgKGkgPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1pXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbiByZWFkSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICBpZiAoISh0aGlzW29mZnNldF0gJiAweDgwKSkgcmV0dXJuICh0aGlzW29mZnNldF0pXG4gIHJldHVybiAoKDB4ZmYgLSB0aGlzW29mZnNldF0gKyAxKSAqIC0xKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkxFID0gZnVuY3Rpb24gcmVhZEludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIDFdIHwgKHRoaXNbb2Zmc2V0XSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyTEUgPSBmdW5jdGlvbiByZWFkSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdKSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10gPDwgMjQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyQkUgPSBmdW5jdGlvbiByZWFkSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDI0KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0TEUgPSBmdW5jdGlvbiByZWFkRmxvYXRMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0QkUgPSBmdW5jdGlvbiByZWFkRmxvYXRCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVMRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgNTIsIDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUJFID0gZnVuY3Rpb24gcmVhZERvdWJsZUJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgNTIsIDgpXG59XG5cbmZ1bmN0aW9uIGNoZWNrSW50IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignYnVmZmVyIG11c3QgYmUgYSBCdWZmZXIgaW5zdGFuY2UnKVxuICBpZiAodmFsdWUgPiBtYXggfHwgdmFsdWUgPCBtaW4pIHRocm93IG5ldyBSYW5nZUVycm9yKCd2YWx1ZSBpcyBvdXQgb2YgYm91bmRzJylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdpbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludExFID0gZnVuY3Rpb24gd3JpdGVVSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSwgMClcblxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludEJFID0gZnVuY3Rpb24gd3JpdGVVSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSwgMClcblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDggPSBmdW5jdGlvbiB3cml0ZVVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4ZmYsIDApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuZnVuY3Rpb24gb2JqZWN0V3JpdGVVSW50MTYgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgMik7IGkgPCBqOyBpKyspIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgJiAoMHhmZiA8PCAoOCAqIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpKSkpID4+PlxuICAgICAgKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkgKiA4XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuZnVuY3Rpb24gb2JqZWN0V3JpdGVVSW50MzIgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmZmZmZiArIHZhbHVlICsgMVxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGJ1Zi5sZW5ndGggLSBvZmZzZXQsIDQpOyBpIDwgajsgaSsrKSB7XG4gICAgYnVmW29mZnNldCArIGldID0gKHZhbHVlID4+PiAobGl0dGxlRW5kaWFuID8gaSA6IDMgLSBpKSAqIDgpICYgMHhmZlxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludExFID0gZnVuY3Rpb24gd3JpdGVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IDBcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IHZhbHVlIDwgMCA/IDEgOiAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gdmFsdWUgPCAwID8gMSA6IDBcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uIHdyaXRlSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweDdmLCAtMHg4MClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmYgKyB2YWx1ZSArIDFcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmZmZmZiArIHZhbHVlICsgMVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuZnVuY3Rpb24gY2hlY2tJRUVFNzU0IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdpbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAob2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gd3JpdGVGbG9hdExFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbiAgcmV0dXJuIG9mZnNldCArIDhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5ICh0YXJnZXQsIHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXRTdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB0YXJnZXRTdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRTdGFydCkgdGFyZ2V0U3RhcnQgPSAwXG4gIGlmIChlbmQgPiAwICYmIGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDBcbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgdGhpcy5sZW5ndGggPT09IDApIHJldHVybiAwXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBpZiAodGFyZ2V0U3RhcnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICB9XG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgKyBzdGFydFxuICB9XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG4gIHZhciBpXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCAmJiBzdGFydCA8IHRhcmdldFN0YXJ0ICYmIHRhcmdldFN0YXJ0IDwgZW5kKSB7XG4gICAgLy8gZGVzY2VuZGluZyBjb3B5IGZyb20gZW5kXG4gICAgZm9yIChpID0gbGVuIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2UgaWYgKGxlbiA8IDEwMDAgfHwgIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gYXNjZW5kaW5nIGNvcHkgZnJvbSBzdGFydFxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgVWludDhBcnJheS5wcm90b3R5cGUuc2V0LmNhbGwoXG4gICAgICB0YXJnZXQsXG4gICAgICB0aGlzLnN1YmFycmF5KHN0YXJ0LCBzdGFydCArIGxlbiksXG4gICAgICB0YXJnZXRTdGFydFxuICAgIClcbiAgfVxuXG4gIHJldHVybiBsZW5cbn1cblxuLy8gZmlsbCh2YWx1ZSwgc3RhcnQ9MCwgZW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiBmaWxsICh2YWx1ZSwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXZhbHVlKSB2YWx1ZSA9IDBcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kKSBlbmQgPSB0aGlzLmxlbmd0aFxuXG4gIGlmIChlbmQgPCBzdGFydCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2VuZCA8IHN0YXJ0JylcblxuICAvLyBGaWxsIDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVyblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDAgfHwgZW5kID4gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdlbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICB0aGlzW2ldID0gdmFsdWVcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGJ5dGVzID0gdXRmOFRvQnl0ZXModmFsdWUudG9TdHJpbmcoKSlcbiAgICB2YXIgbGVuID0gYnl0ZXMubGVuZ3RoXG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgdGhpc1tpXSA9IGJ5dGVzW2kgJSBsZW5dXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PVxuXG52YXIgSU5WQUxJRF9CQVNFNjRfUkUgPSAvW14rXFwvMC05QS1aYS16LV9dL2dcblxuZnVuY3Rpb24gYmFzZTY0Y2xlYW4gKHN0cikge1xuICAvLyBOb2RlIHN0cmlwcyBvdXQgaW52YWxpZCBjaGFyYWN0ZXJzIGxpa2UgXFxuIGFuZCBcXHQgZnJvbSB0aGUgc3RyaW5nLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgc3RyID0gc3RyaW5ndHJpbShzdHIpLnJlcGxhY2UoSU5WQUxJRF9CQVNFNjRfUkUsICcnKVxuICAvLyBOb2RlIGNvbnZlcnRzIHN0cmluZ3Mgd2l0aCBsZW5ndGggPCAyIHRvICcnXG4gIGlmIChzdHIubGVuZ3RoIDwgMikgcmV0dXJuICcnXG4gIC8vIE5vZGUgYWxsb3dzIGZvciBub24tcGFkZGVkIGJhc2U2NCBzdHJpbmdzIChtaXNzaW5nIHRyYWlsaW5nID09PSksIGJhc2U2NC1qcyBkb2VzIG5vdFxuICB3aGlsZSAoc3RyLmxlbmd0aCAlIDQgIT09IDApIHtcbiAgICBzdHIgPSBzdHIgKyAnPSdcbiAgfVxuICByZXR1cm4gc3RyXG59XG5cbmZ1bmN0aW9uIHN0cmluZ3RyaW0gKHN0cikge1xuICBpZiAoc3RyLnRyaW0pIHJldHVybiBzdHIudHJpbSgpXG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpXG59XG5cbmZ1bmN0aW9uIHRvSGV4IChuKSB7XG4gIGlmIChuIDwgMTYpIHJldHVybiAnMCcgKyBuLnRvU3RyaW5nKDE2KVxuICByZXR1cm4gbi50b1N0cmluZygxNilcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMgKHN0cmluZywgdW5pdHMpIHtcbiAgdW5pdHMgPSB1bml0cyB8fCBJbmZpbml0eVxuICB2YXIgY29kZVBvaW50XG4gIHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoXG4gIHZhciBsZWFkU3Vycm9nYXRlID0gbnVsbFxuICB2YXIgYnl0ZXMgPSBbXVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBjb2RlUG9pbnQgPSBzdHJpbmcuY2hhckNvZGVBdChpKVxuXG4gICAgLy8gaXMgc3Vycm9nYXRlIGNvbXBvbmVudFxuICAgIGlmIChjb2RlUG9pbnQgPiAweEQ3RkYgJiYgY29kZVBvaW50IDwgMHhFMDAwKSB7XG4gICAgICAvLyBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCFsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAgIC8vIG5vIGxlYWQgeWV0XG4gICAgICAgIGlmIChjb2RlUG9pbnQgPiAweERCRkYpIHtcbiAgICAgICAgICAvLyB1bmV4cGVjdGVkIHRyYWlsXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfSBlbHNlIGlmIChpICsgMSA9PT0gbGVuZ3RoKSB7XG4gICAgICAgICAgLy8gdW5wYWlyZWQgbGVhZFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyB2YWxpZCBsZWFkXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyAyIGxlYWRzIGluIGEgcm93XG4gICAgICBpZiAoY29kZVBvaW50IDwgMHhEQzAwKSB7XG4gICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIHZhbGlkIHN1cnJvZ2F0ZSBwYWlyXG4gICAgICBjb2RlUG9pbnQgPSAobGVhZFN1cnJvZ2F0ZSAtIDB4RDgwMCA8PCAxMCB8IGNvZGVQb2ludCAtIDB4REMwMCkgKyAweDEwMDAwXG4gICAgfSBlbHNlIGlmIChsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAvLyB2YWxpZCBibXAgY2hhciwgYnV0IGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICB9XG5cbiAgICBsZWFkU3Vycm9nYXRlID0gbnVsbFxuXG4gICAgLy8gZW5jb2RlIHV0ZjhcbiAgICBpZiAoY29kZVBvaW50IDwgMHg4MCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAxKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKGNvZGVQb2ludClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4ODAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgfCAweEMwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAzKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDIHwgMHhFMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gNCkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4MTIgfCAweEYwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvZGUgcG9pbnQnKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBieXRlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVRvQnl0ZXMgKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICAvLyBOb2RlJ3MgY29kZSBzZWVtcyB0byBiZSBkb2luZyB0aGlzIGFuZCBub3QgJiAweDdGLi5cbiAgICBieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSAmIDB4RkYpXG4gIH1cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiB1dGYxNmxlVG9CeXRlcyAoc3RyLCB1bml0cykge1xuICB2YXIgYywgaGksIGxvXG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuXG4gICAgYyA9IHN0ci5jaGFyQ29kZUF0KGkpXG4gICAgaGkgPSBjID4+IDhcbiAgICBsbyA9IGMgJSAyNTZcbiAgICBieXRlQXJyYXkucHVzaChsbylcbiAgICBieXRlQXJyYXkucHVzaChoaSlcbiAgfVxuXG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gYmFzZTY0VG9CeXRlcyAoc3RyKSB7XG4gIHJldHVybiBiYXNlNjQudG9CeXRlQXJyYXkoYmFzZTY0Y2xlYW4oc3RyKSlcbn1cblxuZnVuY3Rpb24gYmxpdEJ1ZmZlciAoc3JjLCBkc3QsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoKGkgKyBvZmZzZXQgPj0gZHN0Lmxlbmd0aCkgfHwgKGkgPj0gc3JjLmxlbmd0aCkpIGJyZWFrXG4gICAgZHN0W2kgKyBvZmZzZXRdID0gc3JjW2ldXG4gIH1cbiAgcmV0dXJuIGlcbn1cbiIsIjsoZnVuY3Rpb24gKGV4cG9ydHMpIHtcbiAgJ3VzZSBzdHJpY3QnXG5cbiAgdmFyIGxvb2t1cCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJ1xuXG4gIHZhciBBcnIgPSAodHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnKVxuICAgID8gVWludDhBcnJheVxuICAgIDogQXJyYXlcblxuICB2YXIgUExVUyA9ICcrJy5jaGFyQ29kZUF0KDApXG4gIHZhciBTTEFTSCA9ICcvJy5jaGFyQ29kZUF0KDApXG4gIHZhciBOVU1CRVIgPSAnMCcuY2hhckNvZGVBdCgwKVxuICB2YXIgTE9XRVIgPSAnYScuY2hhckNvZGVBdCgwKVxuICB2YXIgVVBQRVIgPSAnQScuY2hhckNvZGVBdCgwKVxuICB2YXIgUExVU19VUkxfU0FGRSA9ICctJy5jaGFyQ29kZUF0KDApXG4gIHZhciBTTEFTSF9VUkxfU0FGRSA9ICdfJy5jaGFyQ29kZUF0KDApXG5cbiAgZnVuY3Rpb24gZGVjb2RlIChlbHQpIHtcbiAgICB2YXIgY29kZSA9IGVsdC5jaGFyQ29kZUF0KDApXG4gICAgaWYgKGNvZGUgPT09IFBMVVMgfHwgY29kZSA9PT0gUExVU19VUkxfU0FGRSkgcmV0dXJuIDYyIC8vICcrJ1xuICAgIGlmIChjb2RlID09PSBTTEFTSCB8fCBjb2RlID09PSBTTEFTSF9VUkxfU0FGRSkgcmV0dXJuIDYzIC8vICcvJ1xuICAgIGlmIChjb2RlIDwgTlVNQkVSKSByZXR1cm4gLTEgLy8gbm8gbWF0Y2hcbiAgICBpZiAoY29kZSA8IE5VTUJFUiArIDEwKSByZXR1cm4gY29kZSAtIE5VTUJFUiArIDI2ICsgMjZcbiAgICBpZiAoY29kZSA8IFVQUEVSICsgMjYpIHJldHVybiBjb2RlIC0gVVBQRVJcbiAgICBpZiAoY29kZSA8IExPV0VSICsgMjYpIHJldHVybiBjb2RlIC0gTE9XRVIgKyAyNlxuICB9XG5cbiAgZnVuY3Rpb24gYjY0VG9CeXRlQXJyYXkgKGI2NCkge1xuICAgIHZhciBpLCBqLCBsLCB0bXAsIHBsYWNlSG9sZGVycywgYXJyXG5cbiAgICBpZiAoYjY0Lmxlbmd0aCAlIDQgPiAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuICAgIH1cblxuICAgIC8vIHRoZSBudW1iZXIgb2YgZXF1YWwgc2lnbnMgKHBsYWNlIGhvbGRlcnMpXG4gICAgLy8gaWYgdGhlcmUgYXJlIHR3byBwbGFjZWhvbGRlcnMsIHRoYW4gdGhlIHR3byBjaGFyYWN0ZXJzIGJlZm9yZSBpdFxuICAgIC8vIHJlcHJlc2VudCBvbmUgYnl0ZVxuICAgIC8vIGlmIHRoZXJlIGlzIG9ubHkgb25lLCB0aGVuIHRoZSB0aHJlZSBjaGFyYWN0ZXJzIGJlZm9yZSBpdCByZXByZXNlbnQgMiBieXRlc1xuICAgIC8vIHRoaXMgaXMganVzdCBhIGNoZWFwIGhhY2sgdG8gbm90IGRvIGluZGV4T2YgdHdpY2VcbiAgICB2YXIgbGVuID0gYjY0Lmxlbmd0aFxuICAgIHBsYWNlSG9sZGVycyA9IGI2NC5jaGFyQXQobGVuIC0gMikgPT09ICc9JyA/IDIgOiBiNjQuY2hhckF0KGxlbiAtIDEpID09PSAnPScgPyAxIDogMFxuXG4gICAgLy8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG4gICAgYXJyID0gbmV3IEFycihiNjQubGVuZ3RoICogMyAvIDQgLSBwbGFjZUhvbGRlcnMpXG5cbiAgICAvLyBpZiB0aGVyZSBhcmUgcGxhY2Vob2xkZXJzLCBvbmx5IGdldCB1cCB0byB0aGUgbGFzdCBjb21wbGV0ZSA0IGNoYXJzXG4gICAgbCA9IHBsYWNlSG9sZGVycyA+IDAgPyBiNjQubGVuZ3RoIC0gNCA6IGI2NC5sZW5ndGhcblxuICAgIHZhciBMID0gMFxuXG4gICAgZnVuY3Rpb24gcHVzaCAodikge1xuICAgICAgYXJyW0wrK10gPSB2XG4gICAgfVxuXG4gICAgZm9yIChpID0gMCwgaiA9IDA7IGkgPCBsOyBpICs9IDQsIGogKz0gMykge1xuICAgICAgdG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAxOCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA8PCAxMikgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDIpKSA8PCA2KSB8IGRlY29kZShiNjQuY2hhckF0KGkgKyAzKSlcbiAgICAgIHB1c2goKHRtcCAmIDB4RkYwMDAwKSA+PiAxNilcbiAgICAgIHB1c2goKHRtcCAmIDB4RkYwMCkgPj4gOClcbiAgICAgIHB1c2godG1wICYgMHhGRilcbiAgICB9XG5cbiAgICBpZiAocGxhY2VIb2xkZXJzID09PSAyKSB7XG4gICAgICB0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDIpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAxKSkgPj4gNClcbiAgICAgIHB1c2godG1wICYgMHhGRilcbiAgICB9IGVsc2UgaWYgKHBsYWNlSG9sZGVycyA9PT0gMSkge1xuICAgICAgdG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAxMCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA8PCA0KSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMikpID4+IDIpXG4gICAgICBwdXNoKCh0bXAgPj4gOCkgJiAweEZGKVxuICAgICAgcHVzaCh0bXAgJiAweEZGKVxuICAgIH1cblxuICAgIHJldHVybiBhcnJcbiAgfVxuXG4gIGZ1bmN0aW9uIHVpbnQ4VG9CYXNlNjQgKHVpbnQ4KSB7XG4gICAgdmFyIGlcbiAgICB2YXIgZXh0cmFCeXRlcyA9IHVpbnQ4Lmxlbmd0aCAlIDMgLy8gaWYgd2UgaGF2ZSAxIGJ5dGUgbGVmdCwgcGFkIDIgYnl0ZXNcbiAgICB2YXIgb3V0cHV0ID0gJydcbiAgICB2YXIgdGVtcCwgbGVuZ3RoXG5cbiAgICBmdW5jdGlvbiBlbmNvZGUgKG51bSkge1xuICAgICAgcmV0dXJuIGxvb2t1cC5jaGFyQXQobnVtKVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NCAobnVtKSB7XG4gICAgICByZXR1cm4gZW5jb2RlKG51bSA+PiAxOCAmIDB4M0YpICsgZW5jb2RlKG51bSA+PiAxMiAmIDB4M0YpICsgZW5jb2RlKG51bSA+PiA2ICYgMHgzRikgKyBlbmNvZGUobnVtICYgMHgzRilcbiAgICB9XG5cbiAgICAvLyBnbyB0aHJvdWdoIHRoZSBhcnJheSBldmVyeSB0aHJlZSBieXRlcywgd2UnbGwgZGVhbCB3aXRoIHRyYWlsaW5nIHN0dWZmIGxhdGVyXG4gICAgZm9yIChpID0gMCwgbGVuZ3RoID0gdWludDgubGVuZ3RoIC0gZXh0cmFCeXRlczsgaSA8IGxlbmd0aDsgaSArPSAzKSB7XG4gICAgICB0ZW1wID0gKHVpbnQ4W2ldIDw8IDE2KSArICh1aW50OFtpICsgMV0gPDwgOCkgKyAodWludDhbaSArIDJdKVxuICAgICAgb3V0cHV0ICs9IHRyaXBsZXRUb0Jhc2U2NCh0ZW1wKVxuICAgIH1cblxuICAgIC8vIHBhZCB0aGUgZW5kIHdpdGggemVyb3MsIGJ1dCBtYWtlIHN1cmUgdG8gbm90IGZvcmdldCB0aGUgZXh0cmEgYnl0ZXNcbiAgICBzd2l0Y2ggKGV4dHJhQnl0ZXMpIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgdGVtcCA9IHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDFdXG4gICAgICAgIG91dHB1dCArPSBlbmNvZGUodGVtcCA+PiAyKVxuICAgICAgICBvdXRwdXQgKz0gZW5jb2RlKCh0ZW1wIDw8IDQpICYgMHgzRilcbiAgICAgICAgb3V0cHV0ICs9ICc9PSdcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgdGVtcCA9ICh1aW50OFt1aW50OC5sZW5ndGggLSAyXSA8PCA4KSArICh1aW50OFt1aW50OC5sZW5ndGggLSAxXSlcbiAgICAgICAgb3V0cHV0ICs9IGVuY29kZSh0ZW1wID4+IDEwKVxuICAgICAgICBvdXRwdXQgKz0gZW5jb2RlKCh0ZW1wID4+IDQpICYgMHgzRilcbiAgICAgICAgb3V0cHV0ICs9IGVuY29kZSgodGVtcCA8PCAyKSAmIDB4M0YpXG4gICAgICAgIG91dHB1dCArPSAnPSdcbiAgICAgICAgYnJlYWtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrXG4gICAgfVxuXG4gICAgcmV0dXJuIG91dHB1dFxuICB9XG5cbiAgZXhwb3J0cy50b0J5dGVBcnJheSA9IGI2NFRvQnl0ZUFycmF5XG4gIGV4cG9ydHMuZnJvbUJ5dGVBcnJheSA9IHVpbnQ4VG9CYXNlNjRcbn0odHlwZW9mIGV4cG9ydHMgPT09ICd1bmRlZmluZWQnID8gKHRoaXMuYmFzZTY0anMgPSB7fSkgOiBleHBvcnRzKSlcbiIsImV4cG9ydHMucmVhZCA9IGZ1bmN0aW9uIChidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtXG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgbkJpdHMgPSAtN1xuICB2YXIgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwXG4gIHZhciBkID0gaXNMRSA/IC0xIDogMVxuICB2YXIgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXVxuXG4gIGkgKz0gZFxuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIHMgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IGVMZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IGUgKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBlID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBtTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSBtICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgaWYgKGUgPT09IDApIHtcbiAgICBlID0gMSAtIGVCaWFzXG4gIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KVxuICB9IGVsc2Uge1xuICAgIG0gPSBtICsgTWF0aC5wb3coMiwgbUxlbilcbiAgICBlID0gZSAtIGVCaWFzXG4gIH1cbiAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbilcbn1cblxuZXhwb3J0cy53cml0ZSA9IGZ1bmN0aW9uIChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbSwgY1xuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKVxuICB2YXIgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpXG4gIHZhciBkID0gaXNMRSA/IDEgOiAtMVxuICB2YXIgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMFxuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpXG5cbiAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcbiAgICBtID0gaXNOYU4odmFsdWUpID8gMSA6IDBcbiAgICBlID0gZU1heFxuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKVxuICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcbiAgICAgIGUtLVxuICAgICAgYyAqPSAyXG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKVxuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrK1xuICAgICAgYyAvPSAyXG4gICAgfVxuXG4gICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG4gICAgICBtID0gMFxuICAgICAgZSA9IGVNYXhcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKHZhbHVlICogYyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSBlICsgZUJpYXNcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gMFxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbVxuICBlTGVuICs9IG1MZW5cbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyOFxufVxuIiwidmFyIHRvU3RyaW5nID0ge30udG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoYXJyKSB7XG4gIHJldHVybiB0b1N0cmluZy5jYWxsKGFycikgPT0gJ1tvYmplY3QgQXJyYXldJztcbn07XG4iLCIndXNlIHN0cmljdCdcblxuZXhwb3J0cy5yYW5kb21CeXRlcyA9IGV4cG9ydHMucm5nID0gZXhwb3J0cy5wc2V1ZG9SYW5kb21CeXRlcyA9IGV4cG9ydHMucHJuZyA9IHJlcXVpcmUoJ3JhbmRvbWJ5dGVzJylcbmV4cG9ydHMuY3JlYXRlSGFzaCA9IGV4cG9ydHMuSGFzaCA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoJylcbmV4cG9ydHMuY3JlYXRlSG1hYyA9IGV4cG9ydHMuSG1hYyA9IHJlcXVpcmUoJ2NyZWF0ZS1obWFjJylcblxudmFyIGhhc2hlcyA9IFsnc2hhMScsICdzaGEyMjQnLCAnc2hhMjU2JywgJ3NoYTM4NCcsICdzaGE1MTInLCAnbWQ1JywgJ3JtZDE2MCddLmNvbmNhdChPYmplY3Qua2V5cyhyZXF1aXJlKCdicm93c2VyaWZ5LXNpZ24vYWxnb3MnKSkpXG5leHBvcnRzLmdldEhhc2hlcyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIGhhc2hlc1xufVxuXG52YXIgcCA9IHJlcXVpcmUoJ3Bia2RmMicpXG5leHBvcnRzLnBia2RmMiA9IHAucGJrZGYyXG5leHBvcnRzLnBia2RmMlN5bmMgPSBwLnBia2RmMlN5bmNcblxudmFyIGFlcyA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktY2lwaGVyJylcbjtbXG4gICdDaXBoZXInLFxuICAnY3JlYXRlQ2lwaGVyJyxcbiAgJ0NpcGhlcml2JyxcbiAgJ2NyZWF0ZUNpcGhlcml2JyxcbiAgJ0RlY2lwaGVyJyxcbiAgJ2NyZWF0ZURlY2lwaGVyJyxcbiAgJ0RlY2lwaGVyaXYnLFxuICAnY3JlYXRlRGVjaXBoZXJpdicsXG4gICdnZXRDaXBoZXJzJyxcbiAgJ2xpc3RDaXBoZXJzJ1xuXS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgZXhwb3J0c1trZXldID0gYWVzW2tleV1cbn0pXG5cbnZhciBkaCA9IHJlcXVpcmUoJ2RpZmZpZS1oZWxsbWFuJylcbjtbXG4gICdEaWZmaWVIZWxsbWFuR3JvdXAnLFxuICAnY3JlYXRlRGlmZmllSGVsbG1hbkdyb3VwJyxcbiAgJ2dldERpZmZpZUhlbGxtYW4nLFxuICAnY3JlYXRlRGlmZmllSGVsbG1hbicsXG4gICdEaWZmaWVIZWxsbWFuJ1xuXS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgZXhwb3J0c1trZXldID0gZGhba2V5XVxufSlcblxudmFyIHNpZ24gPSByZXF1aXJlKCdicm93c2VyaWZ5LXNpZ24nKVxuO1tcbiAgJ2NyZWF0ZVNpZ24nLFxuICAnU2lnbicsXG4gICdjcmVhdGVWZXJpZnknLFxuICAnVmVyaWZ5J1xuXS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgZXhwb3J0c1trZXldID0gc2lnbltrZXldXG59KVxuXG5leHBvcnRzLmNyZWF0ZUVDREggPSByZXF1aXJlKCdjcmVhdGUtZWNkaCcpXG5cbnZhciBwdWJsaWNFbmNyeXB0ID0gcmVxdWlyZSgncHVibGljLWVuY3J5cHQnKVxuXG47W1xuICAncHVibGljRW5jcnlwdCcsXG4gICdwcml2YXRlRW5jcnlwdCcsXG4gICdwdWJsaWNEZWNyeXB0JyxcbiAgJ3ByaXZhdGVEZWNyeXB0J1xuXS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgZXhwb3J0c1trZXldID0gcHVibGljRW5jcnlwdFtrZXldXG59KVxuXG4vLyB0aGUgbGVhc3QgSSBjYW4gZG8gaXMgbWFrZSBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIHJlc3Qgb2YgdGhlIG5vZGUuanMvY3J5cHRvIGFwaS5cbjtbXG4gICdjcmVhdGVDcmVkZW50aWFscydcbl0uZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICBleHBvcnRzW25hbWVdID0gZnVuY3Rpb24gKCkge1xuICAgIHRocm93IG5ldyBFcnJvcihbXG4gICAgICAnc29ycnksICcgKyBuYW1lICsgJyBpcyBub3QgaW1wbGVtZW50ZWQgeWV0JyxcbiAgICAgICd3ZSBhY2NlcHQgcHVsbCByZXF1ZXN0cycsXG4gICAgICAnaHR0cHM6Ly9naXRodWIuY29tL2NyeXB0by1icm93c2VyaWZ5L2NyeXB0by1icm93c2VyaWZ5J1xuICAgIF0uam9pbignXFxuJykpXG4gIH1cbn0pXG4iLCJ2YXIgZWJ0ayA9IHJlcXVpcmUoJ2V2cF9ieXRlc3Rva2V5JylcbnZhciBhZXMgPSByZXF1aXJlKCdicm93c2VyaWZ5LWFlcy9icm93c2VyJylcbnZhciBERVMgPSByZXF1aXJlKCdicm93c2VyaWZ5LWRlcycpXG52YXIgZGVzTW9kZXMgPSByZXF1aXJlKCdicm93c2VyaWZ5LWRlcy9tb2RlcycpXG52YXIgYWVzTW9kZXMgPSByZXF1aXJlKCdicm93c2VyaWZ5LWFlcy9tb2RlcycpXG5mdW5jdGlvbiBjcmVhdGVDaXBoZXIgKHN1aXRlLCBwYXNzd29yZCkge1xuICB2YXIga2V5TGVuLCBpdkxlblxuICBzdWl0ZSA9IHN1aXRlLnRvTG93ZXJDYXNlKClcbiAgaWYgKGFlc01vZGVzW3N1aXRlXSkge1xuICAgIGtleUxlbiA9IGFlc01vZGVzW3N1aXRlXS5rZXlcbiAgICBpdkxlbiA9IGFlc01vZGVzW3N1aXRlXS5pdlxuICB9IGVsc2UgaWYgKGRlc01vZGVzW3N1aXRlXSkge1xuICAgIGtleUxlbiA9IGRlc01vZGVzW3N1aXRlXS5rZXkgKiA4XG4gICAgaXZMZW4gPSBkZXNNb2Rlc1tzdWl0ZV0uaXZcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuICB9XG4gIHZhciBrZXlzID0gZWJ0ayhwYXNzd29yZCwgZmFsc2UsIGtleUxlbiwgaXZMZW4pXG4gIHJldHVybiBjcmVhdGVDaXBoZXJpdihzdWl0ZSwga2V5cy5rZXksIGtleXMuaXYpXG59XG5mdW5jdGlvbiBjcmVhdGVEZWNpcGhlciAoc3VpdGUsIHBhc3N3b3JkKSB7XG4gIHZhciBrZXlMZW4sIGl2TGVuXG4gIHN1aXRlID0gc3VpdGUudG9Mb3dlckNhc2UoKVxuICBpZiAoYWVzTW9kZXNbc3VpdGVdKSB7XG4gICAga2V5TGVuID0gYWVzTW9kZXNbc3VpdGVdLmtleVxuICAgIGl2TGVuID0gYWVzTW9kZXNbc3VpdGVdLml2XG4gIH0gZWxzZSBpZiAoZGVzTW9kZXNbc3VpdGVdKSB7XG4gICAga2V5TGVuID0gZGVzTW9kZXNbc3VpdGVdLmtleSAqIDhcbiAgICBpdkxlbiA9IGRlc01vZGVzW3N1aXRlXS5pdlxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgdmFyIGtleXMgPSBlYnRrKHBhc3N3b3JkLCBmYWxzZSwga2V5TGVuLCBpdkxlbilcbiAgcmV0dXJuIGNyZWF0ZURlY2lwaGVyaXYoc3VpdGUsIGtleXMua2V5LCBrZXlzLml2KVxufVxuXG5mdW5jdGlvbiBjcmVhdGVDaXBoZXJpdiAoc3VpdGUsIGtleSwgaXYpIHtcbiAgc3VpdGUgPSBzdWl0ZS50b0xvd2VyQ2FzZSgpXG4gIGlmIChhZXNNb2Rlc1tzdWl0ZV0pIHtcbiAgICByZXR1cm4gYWVzLmNyZWF0ZUNpcGhlcml2KHN1aXRlLCBrZXksIGl2KVxuICB9IGVsc2UgaWYgKGRlc01vZGVzW3N1aXRlXSkge1xuICAgIHJldHVybiBuZXcgREVTKHtcbiAgICAgIGtleToga2V5LFxuICAgICAgaXY6IGl2LFxuICAgICAgbW9kZTogc3VpdGVcbiAgICB9KVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbn1cbmZ1bmN0aW9uIGNyZWF0ZURlY2lwaGVyaXYgKHN1aXRlLCBrZXksIGl2KSB7XG4gIHN1aXRlID0gc3VpdGUudG9Mb3dlckNhc2UoKVxuICBpZiAoYWVzTW9kZXNbc3VpdGVdKSB7XG4gICAgcmV0dXJuIGFlcy5jcmVhdGVEZWNpcGhlcml2KHN1aXRlLCBrZXksIGl2KVxuICB9IGVsc2UgaWYgKGRlc01vZGVzW3N1aXRlXSkge1xuICAgIHJldHVybiBuZXcgREVTKHtcbiAgICAgIGtleToga2V5LFxuICAgICAgaXY6IGl2LFxuICAgICAgbW9kZTogc3VpdGUsXG4gICAgICBkZWNyeXB0OiB0cnVlXG4gICAgfSlcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuICB9XG59XG5leHBvcnRzLmNyZWF0ZUNpcGhlciA9IGV4cG9ydHMuQ2lwaGVyID0gY3JlYXRlQ2lwaGVyXG5leHBvcnRzLmNyZWF0ZUNpcGhlcml2ID0gZXhwb3J0cy5DaXBoZXJpdiA9IGNyZWF0ZUNpcGhlcml2XG5leHBvcnRzLmNyZWF0ZURlY2lwaGVyID0gZXhwb3J0cy5EZWNpcGhlciA9IGNyZWF0ZURlY2lwaGVyXG5leHBvcnRzLmNyZWF0ZURlY2lwaGVyaXYgPSBleHBvcnRzLkRlY2lwaGVyaXYgPSBjcmVhdGVEZWNpcGhlcml2XG5mdW5jdGlvbiBnZXRDaXBoZXJzICgpIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKGRlc01vZGVzKS5jb25jYXQoYWVzLmdldENpcGhlcnMoKSlcbn1cbmV4cG9ydHMubGlzdENpcGhlcnMgPSBleHBvcnRzLmdldENpcGhlcnMgPSBnZXRDaXBoZXJzXG4iLCIvLyBiYXNlZCBvbiB0aGUgYWVzIGltcGxpbWVudGF0aW9uIGluIHRyaXBsZSBzZWNcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9rZXliYXNlL3RyaXBsZXNlY1xuXG4vLyB3aGljaCBpcyBpbiB0dXJuIGJhc2VkIG9uIHRoZSBvbmUgZnJvbSBjcnlwdG8tanNcbi8vIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzL1xuXG52YXIgdWludF9tYXggPSBNYXRoLnBvdygyLCAzMilcbmZ1bmN0aW9uIGZpeHVwX3VpbnQzMiAoeCkge1xuICB2YXIgcmV0LCB4X3Bvc1xuICByZXQgPSB4ID4gdWludF9tYXggfHwgeCA8IDAgPyAoeF9wb3MgPSBNYXRoLmFicyh4KSAlIHVpbnRfbWF4LCB4IDwgMCA/IHVpbnRfbWF4IC0geF9wb3MgOiB4X3BvcykgOiB4XG4gIHJldHVybiByZXRcbn1cbmZ1bmN0aW9uIHNjcnViX3ZlYyAodikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHYubGVuZ3RoOyB2KyspIHtcbiAgICB2W2ldID0gMFxuICB9XG4gIHJldHVybiBmYWxzZVxufVxuXG5mdW5jdGlvbiBHbG9iYWwgKCkge1xuICB0aGlzLlNCT1ggPSBbXVxuICB0aGlzLklOVl9TQk9YID0gW11cbiAgdGhpcy5TVUJfTUlYID0gW1tdLCBbXSwgW10sIFtdXVxuICB0aGlzLklOVl9TVUJfTUlYID0gW1tdLCBbXSwgW10sIFtdXVxuICB0aGlzLmluaXQoKVxuICB0aGlzLlJDT04gPSBbMHgwMCwgMHgwMSwgMHgwMiwgMHgwNCwgMHgwOCwgMHgxMCwgMHgyMCwgMHg0MCwgMHg4MCwgMHgxYiwgMHgzNl1cbn1cblxuR2xvYmFsLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgZCwgaSwgc3gsIHQsIHgsIHgyLCB4NCwgeDgsIHhpLCBfaVxuICBkID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgX2ksIF9yZXN1bHRzXG4gICAgX3Jlc3VsdHMgPSBbXVxuICAgIGZvciAoaSA9IF9pID0gMDsgX2kgPCAyNTY7IGkgPSArK19pKSB7XG4gICAgICBpZiAoaSA8IDEyOCkge1xuICAgICAgICBfcmVzdWx0cy5wdXNoKGkgPDwgMSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIF9yZXN1bHRzLnB1c2goKGkgPDwgMSkgXiAweDExYilcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIF9yZXN1bHRzXG4gIH0pKClcbiAgeCA9IDBcbiAgeGkgPSAwXG4gIGZvciAoaSA9IF9pID0gMDsgX2kgPCAyNTY7IGkgPSArK19pKSB7XG4gICAgc3ggPSB4aSBeICh4aSA8PCAxKSBeICh4aSA8PCAyKSBeICh4aSA8PCAzKSBeICh4aSA8PCA0KVxuICAgIHN4ID0gKHN4ID4+PiA4KSBeIChzeCAmIDB4ZmYpIF4gMHg2M1xuICAgIHRoaXMuU0JPWFt4XSA9IHN4XG4gICAgdGhpcy5JTlZfU0JPWFtzeF0gPSB4XG4gICAgeDIgPSBkW3hdXG4gICAgeDQgPSBkW3gyXVxuICAgIHg4ID0gZFt4NF1cbiAgICB0ID0gKGRbc3hdICogMHgxMDEpIF4gKHN4ICogMHgxMDEwMTAwKVxuICAgIHRoaXMuU1VCX01JWFswXVt4XSA9ICh0IDw8IDI0KSB8ICh0ID4+PiA4KVxuICAgIHRoaXMuU1VCX01JWFsxXVt4XSA9ICh0IDw8IDE2KSB8ICh0ID4+PiAxNilcbiAgICB0aGlzLlNVQl9NSVhbMl1beF0gPSAodCA8PCA4KSB8ICh0ID4+PiAyNClcbiAgICB0aGlzLlNVQl9NSVhbM11beF0gPSB0XG4gICAgdCA9ICh4OCAqIDB4MTAxMDEwMSkgXiAoeDQgKiAweDEwMDAxKSBeICh4MiAqIDB4MTAxKSBeICh4ICogMHgxMDEwMTAwKVxuICAgIHRoaXMuSU5WX1NVQl9NSVhbMF1bc3hdID0gKHQgPDwgMjQpIHwgKHQgPj4+IDgpXG4gICAgdGhpcy5JTlZfU1VCX01JWFsxXVtzeF0gPSAodCA8PCAxNikgfCAodCA+Pj4gMTYpXG4gICAgdGhpcy5JTlZfU1VCX01JWFsyXVtzeF0gPSAodCA8PCA4KSB8ICh0ID4+PiAyNClcbiAgICB0aGlzLklOVl9TVUJfTUlYWzNdW3N4XSA9IHRcbiAgICBpZiAoeCA9PT0gMCkge1xuICAgICAgeCA9IHhpID0gMVxuICAgIH0gZWxzZSB7XG4gICAgICB4ID0geDIgXiBkW2RbZFt4OCBeIHgyXV1dXG4gICAgICB4aSBePSBkW2RbeGldXVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG52YXIgRyA9IG5ldyBHbG9iYWwoKVxuXG5BRVMuYmxvY2tTaXplID0gNCAqIDRcblxuQUVTLnByb3RvdHlwZS5ibG9ja1NpemUgPSBBRVMuYmxvY2tTaXplXG5cbkFFUy5rZXlTaXplID0gMjU2IC8gOFxuXG5BRVMucHJvdG90eXBlLmtleVNpemUgPSBBRVMua2V5U2l6ZVxuXG5mdW5jdGlvbiBidWZmZXJUb0FycmF5IChidWYpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGggLyA0XG4gIHZhciBvdXQgPSBuZXcgQXJyYXkobGVuKVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXRbaV0gPSBidWYucmVhZFVJbnQzMkJFKGkgKiA0KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbmZ1bmN0aW9uIEFFUyAoa2V5KSB7XG4gIHRoaXMuX2tleSA9IGJ1ZmZlclRvQXJyYXkoa2V5KVxuICB0aGlzLl9kb1Jlc2V0KClcbn1cblxuQUVTLnByb3RvdHlwZS5fZG9SZXNldCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGludktzUm93LCBrZXlTaXplLCBrZXlXb3Jkcywga3NSb3csIGtzUm93cywgdFxuICBrZXlXb3JkcyA9IHRoaXMuX2tleVxuICBrZXlTaXplID0ga2V5V29yZHMubGVuZ3RoXG4gIHRoaXMuX25Sb3VuZHMgPSBrZXlTaXplICsgNlxuICBrc1Jvd3MgPSAodGhpcy5fblJvdW5kcyArIDEpICogNFxuICB0aGlzLl9rZXlTY2hlZHVsZSA9IFtdXG4gIGZvciAoa3NSb3cgPSAwOyBrc1JvdyA8IGtzUm93czsga3NSb3crKykge1xuICAgIHRoaXMuX2tleVNjaGVkdWxlW2tzUm93XSA9IGtzUm93IDwga2V5U2l6ZSA/IGtleVdvcmRzW2tzUm93XSA6ICh0ID0gdGhpcy5fa2V5U2NoZWR1bGVba3NSb3cgLSAxXSwgKGtzUm93ICUga2V5U2l6ZSkgPT09IDAgPyAodCA9ICh0IDw8IDgpIHwgKHQgPj4+IDI0KSwgdCA9IChHLlNCT1hbdCA+Pj4gMjRdIDw8IDI0KSB8IChHLlNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChHLlNCT1hbKHQgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBHLlNCT1hbdCAmIDB4ZmZdLCB0IF49IEcuUkNPTlsoa3NSb3cgLyBrZXlTaXplKSB8IDBdIDw8IDI0KSA6IGtleVNpemUgPiA2ICYmIGtzUm93ICUga2V5U2l6ZSA9PT0gNCA/IHQgPSAoRy5TQk9YW3QgPj4+IDI0XSA8PCAyNCkgfCAoRy5TQk9YWyh0ID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoRy5TQk9YWyh0ID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgRy5TQk9YW3QgJiAweGZmXSA6IHZvaWQgMCwgdGhpcy5fa2V5U2NoZWR1bGVba3NSb3cgLSBrZXlTaXplXSBeIHQpXG4gIH1cbiAgdGhpcy5faW52S2V5U2NoZWR1bGUgPSBbXVxuICBmb3IgKGludktzUm93ID0gMDsgaW52S3NSb3cgPCBrc1Jvd3M7IGludktzUm93KyspIHtcbiAgICBrc1JvdyA9IGtzUm93cyAtIGludktzUm93XG4gICAgdCA9IHRoaXMuX2tleVNjaGVkdWxlW2tzUm93IC0gKGludktzUm93ICUgNCA/IDAgOiA0KV1cbiAgICB0aGlzLl9pbnZLZXlTY2hlZHVsZVtpbnZLc1Jvd10gPSBpbnZLc1JvdyA8IDQgfHwga3NSb3cgPD0gNCA/IHQgOiBHLklOVl9TVUJfTUlYWzBdW0cuU0JPWFt0ID4+PiAyNF1dIF4gRy5JTlZfU1VCX01JWFsxXVtHLlNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdXSBeIEcuSU5WX1NVQl9NSVhbMl1bRy5TQk9YWyh0ID4+PiA4KSAmIDB4ZmZdXSBeIEcuSU5WX1NVQl9NSVhbM11bRy5TQk9YW3QgJiAweGZmXV1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG5BRVMucHJvdG90eXBlLmVuY3J5cHRCbG9jayA9IGZ1bmN0aW9uIChNKSB7XG4gIE0gPSBidWZmZXJUb0FycmF5KG5ldyBCdWZmZXIoTSkpXG4gIHZhciBvdXQgPSB0aGlzLl9kb0NyeXB0QmxvY2soTSwgdGhpcy5fa2V5U2NoZWR1bGUsIEcuU1VCX01JWCwgRy5TQk9YKVxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcigxNilcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzBdLCAwKVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMV0sIDQpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsyXSwgOClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzNdLCAxMilcbiAgcmV0dXJuIGJ1ZlxufVxuXG5BRVMucHJvdG90eXBlLmRlY3J5cHRCbG9jayA9IGZ1bmN0aW9uIChNKSB7XG4gIE0gPSBidWZmZXJUb0FycmF5KG5ldyBCdWZmZXIoTSkpXG4gIHZhciB0ZW1wID0gW01bM10sIE1bMV1dXG4gIE1bMV0gPSB0ZW1wWzBdXG4gIE1bM10gPSB0ZW1wWzFdXG4gIHZhciBvdXQgPSB0aGlzLl9kb0NyeXB0QmxvY2soTSwgdGhpcy5faW52S2V5U2NoZWR1bGUsIEcuSU5WX1NVQl9NSVgsIEcuSU5WX1NCT1gpXG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKDE2KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMF0sIDApXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFszXSwgNClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzJdLCA4KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMV0sIDEyKVxuICByZXR1cm4gYnVmXG59XG5cbkFFUy5wcm90b3R5cGUuc2NydWIgPSBmdW5jdGlvbiAoKSB7XG4gIHNjcnViX3ZlYyh0aGlzLl9rZXlTY2hlZHVsZSlcbiAgc2NydWJfdmVjKHRoaXMuX2ludktleVNjaGVkdWxlKVxuICBzY3J1Yl92ZWModGhpcy5fa2V5KVxufVxuXG5BRVMucHJvdG90eXBlLl9kb0NyeXB0QmxvY2sgPSBmdW5jdGlvbiAoTSwga2V5U2NoZWR1bGUsIFNVQl9NSVgsIFNCT1gpIHtcbiAgdmFyIGtzUm93LCBzMCwgczEsIHMyLCBzMywgdDAsIHQxLCB0MiwgdDNcblxuICBzMCA9IE1bMF0gXiBrZXlTY2hlZHVsZVswXVxuICBzMSA9IE1bMV0gXiBrZXlTY2hlZHVsZVsxXVxuICBzMiA9IE1bMl0gXiBrZXlTY2hlZHVsZVsyXVxuICBzMyA9IE1bM10gXiBrZXlTY2hlZHVsZVszXVxuICBrc1JvdyA9IDRcbiAgZm9yICh2YXIgcm91bmQgPSAxOyByb3VuZCA8IHRoaXMuX25Sb3VuZHM7IHJvdW5kKyspIHtcbiAgICB0MCA9IFNVQl9NSVhbMF1bczAgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMxID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMyID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMyAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MSA9IFNVQl9NSVhbMF1bczEgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMyID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMzID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMCAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MiA9IFNVQl9NSVhbMF1bczIgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMzID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMwID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMSAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MyA9IFNVQl9NSVhbMF1bczMgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMwID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMxID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMiAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICBzMCA9IHQwXG4gICAgczEgPSB0MVxuICAgIHMyID0gdDJcbiAgICBzMyA9IHQzXG4gIH1cbiAgdDAgPSAoKFNCT1hbczAgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczEgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMiA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczMgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICB0MSA9ICgoU0JPWFtzMSA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMiA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMzID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMCAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gIHQyID0gKChTQk9YW3MyID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMzID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczAgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MxICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgdDMgPSAoKFNCT1hbczMgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczAgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMSA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczIgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICByZXR1cm4gW1xuICAgIGZpeHVwX3VpbnQzMih0MCksXG4gICAgZml4dXBfdWludDMyKHQxKSxcbiAgICBmaXh1cF91aW50MzIodDIpLFxuICAgIGZpeHVwX3VpbnQzMih0MylcbiAgXVxufVxuXG5leHBvcnRzLkFFUyA9IEFFU1xuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgR0hBU0ggPSByZXF1aXJlKCcuL2doYXNoJylcbnZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcbmluaGVyaXRzKFN0cmVhbUNpcGhlciwgVHJhbnNmb3JtKVxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW1DaXBoZXJcblxuZnVuY3Rpb24gU3RyZWFtQ2lwaGVyIChtb2RlLCBrZXksIGl2LCBkZWNyeXB0KSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTdHJlYW1DaXBoZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBTdHJlYW1DaXBoZXIobW9kZSwga2V5LCBpdilcbiAgfVxuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuICB0aGlzLl9maW5JRCA9IEJ1ZmZlci5jb25jYXQoW2l2LCBuZXcgQnVmZmVyKFswLCAwLCAwLCAxXSldKVxuICBpdiA9IEJ1ZmZlci5jb25jYXQoW2l2LCBuZXcgQnVmZmVyKFswLCAwLCAwLCAyXSldKVxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHRoaXMuX3ByZXYgPSBuZXcgQnVmZmVyKGl2Lmxlbmd0aClcbiAgdGhpcy5fY2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxuICB0aGlzLl9zZWNDYWNoZSA9IG5ldyBCdWZmZXIoJycpXG4gIHRoaXMuX2RlY3J5cHQgPSBkZWNyeXB0XG4gIHRoaXMuX2FsZW4gPSAwXG4gIHRoaXMuX2xlbiA9IDBcbiAgaXYuY29weSh0aGlzLl9wcmV2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxuICB2YXIgaCA9IG5ldyBCdWZmZXIoNClcbiAgaC5maWxsKDApXG4gIHRoaXMuX2doYXNoID0gbmV3IEdIQVNIKHRoaXMuX2NpcGhlci5lbmNyeXB0QmxvY2soaCkpXG4gIHRoaXMuX2F1dGhUYWcgPSBudWxsXG4gIHRoaXMuX2NhbGxlZCA9IGZhbHNlXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgaWYgKCF0aGlzLl9jYWxsZWQgJiYgdGhpcy5fYWxlbikge1xuICAgIHZhciBydW1wID0gMTYgLSAodGhpcy5fYWxlbiAlIDE2KVxuICAgIGlmIChydW1wIDwgMTYpIHtcbiAgICAgIHJ1bXAgPSBuZXcgQnVmZmVyKHJ1bXApXG4gICAgICBydW1wLmZpbGwoMClcbiAgICAgIHRoaXMuX2doYXNoLnVwZGF0ZShydW1wKVxuICAgIH1cbiAgfVxuICB0aGlzLl9jYWxsZWQgPSB0cnVlXG4gIHZhciBvdXQgPSB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmspXG4gIGlmICh0aGlzLl9kZWNyeXB0KSB7XG4gICAgdGhpcy5fZ2hhc2gudXBkYXRlKGNodW5rKVxuICB9IGVsc2Uge1xuICAgIHRoaXMuX2doYXNoLnVwZGF0ZShvdXQpXG4gIH1cbiAgdGhpcy5fbGVuICs9IGNodW5rLmxlbmd0aFxuICByZXR1cm4gb3V0XG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuX2RlY3J5cHQgJiYgIXRoaXMuX2F1dGhUYWcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIHN0YXRlIG9yIHVuYWJsZSB0byBhdXRoZW50aWNhdGUgZGF0YScpXG4gIH1cbiAgdmFyIHRhZyA9IHhvcih0aGlzLl9naGFzaC5maW5hbCh0aGlzLl9hbGVuICogOCwgdGhpcy5fbGVuICogOCksIHRoaXMuX2NpcGhlci5lbmNyeXB0QmxvY2sodGhpcy5fZmluSUQpKVxuICBpZiAodGhpcy5fZGVjcnlwdCkge1xuICAgIGlmICh4b3JUZXN0KHRhZywgdGhpcy5fYXV0aFRhZykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgc3RhdGUgb3IgdW5hYmxlIHRvIGF1dGhlbnRpY2F0ZSBkYXRhJylcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fYXV0aFRhZyA9IHRhZ1xuICB9XG4gIHRoaXMuX2NpcGhlci5zY3J1YigpXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiBnZXRBdXRoVGFnICgpIHtcbiAgaWYgKCF0aGlzLl9kZWNyeXB0ICYmIEJ1ZmZlci5pc0J1ZmZlcih0aGlzLl9hdXRoVGFnKSkge1xuICAgIHJldHVybiB0aGlzLl9hdXRoVGFnXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG4gIH1cbn1cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuc2V0QXV0aFRhZyA9IGZ1bmN0aW9uIHNldEF1dGhUYWcgKHRhZykge1xuICBpZiAodGhpcy5fZGVjcnlwdCkge1xuICAgIHRoaXMuX2F1dGhUYWcgPSB0YWdcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0F0dGVtcHRpbmcgdG8gc2V0IGF1dGggdGFnIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbiAgfVxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5zZXRBQUQgPSBmdW5jdGlvbiBzZXRBQUQgKGJ1Zikge1xuICBpZiAoIXRoaXMuX2NhbGxlZCkge1xuICAgIHRoaXMuX2doYXNoLnVwZGF0ZShidWYpXG4gICAgdGhpcy5fYWxlbiArPSBidWYubGVuZ3RoXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIHNldCBBQUQgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxuICB9XG59XG5mdW5jdGlvbiB4b3JUZXN0IChhLCBiKSB7XG4gIHZhciBvdXQgPSAwXG4gIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHtcbiAgICBvdXQrK1xuICB9XG4gIHZhciBsZW4gPSBNYXRoLm1pbihhLmxlbmd0aCwgYi5sZW5ndGgpXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dCArPSAoYVtpXSBeIGJbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwidmFyIGNpcGhlcnMgPSByZXF1aXJlKCcuL2VuY3J5cHRlcicpXG5leHBvcnRzLmNyZWF0ZUNpcGhlciA9IGV4cG9ydHMuQ2lwaGVyID0gY2lwaGVycy5jcmVhdGVDaXBoZXJcbmV4cG9ydHMuY3JlYXRlQ2lwaGVyaXYgPSBleHBvcnRzLkNpcGhlcml2ID0gY2lwaGVycy5jcmVhdGVDaXBoZXJpdlxudmFyIGRlY2lwaGVycyA9IHJlcXVpcmUoJy4vZGVjcnlwdGVyJylcbmV4cG9ydHMuY3JlYXRlRGVjaXBoZXIgPSBleHBvcnRzLkRlY2lwaGVyID0gZGVjaXBoZXJzLmNyZWF0ZURlY2lwaGVyXG5leHBvcnRzLmNyZWF0ZURlY2lwaGVyaXYgPSBleHBvcnRzLkRlY2lwaGVyaXYgPSBkZWNpcGhlcnMuY3JlYXRlRGVjaXBoZXJpdlxudmFyIG1vZGVzID0gcmVxdWlyZSgnLi9tb2RlcycpXG5mdW5jdGlvbiBnZXRDaXBoZXJzICgpIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKG1vZGVzKVxufVxuZXhwb3J0cy5saXN0Q2lwaGVycyA9IGV4cG9ydHMuZ2V0Q2lwaGVycyA9IGdldENpcGhlcnNcbiIsInZhciBhZXMgPSByZXF1aXJlKCcuL2FlcycpXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIG1vZGVzID0gcmVxdWlyZSgnLi9tb2RlcycpXG52YXIgU3RyZWFtQ2lwaGVyID0gcmVxdWlyZSgnLi9zdHJlYW1DaXBoZXInKVxudmFyIEF1dGhDaXBoZXIgPSByZXF1aXJlKCcuL2F1dGhDaXBoZXInKVxudmFyIGVidGsgPSByZXF1aXJlKCdldnBfYnl0ZXN0b2tleScpXG5cbmluaGVyaXRzKERlY2lwaGVyLCBUcmFuc2Zvcm0pXG5mdW5jdGlvbiBEZWNpcGhlciAobW9kZSwga2V5LCBpdikge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgRGVjaXBoZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBEZWNpcGhlcihtb2RlLCBrZXksIGl2KVxuICB9XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG4gIHRoaXMuX2NhY2hlID0gbmV3IFNwbGl0dGVyKClcbiAgdGhpcy5fbGFzdCA9IHZvaWQgMFxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHRoaXMuX3ByZXYgPSBuZXcgQnVmZmVyKGl2Lmxlbmd0aClcbiAgaXYuY29weSh0aGlzLl9wcmV2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxuICB0aGlzLl9hdXRvcGFkZGluZyA9IHRydWVcbn1cbkRlY2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5fY2FjaGUuYWRkKGRhdGEpXG4gIHZhciBjaHVua1xuICB2YXIgdGhpbmdcbiAgdmFyIG91dCA9IFtdXG4gIHdoaWxlICgoY2h1bmsgPSB0aGlzLl9jYWNoZS5nZXQodGhpcy5fYXV0b3BhZGRpbmcpKSkge1xuICAgIHRoaW5nID0gdGhpcy5fbW9kZS5kZWNyeXB0KHRoaXMsIGNodW5rKVxuICAgIG91dC5wdXNoKHRoaW5nKVxuICB9XG4gIHJldHVybiBCdWZmZXIuY29uY2F0KG91dClcbn1cbkRlY2lwaGVyLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBjaHVuayA9IHRoaXMuX2NhY2hlLmZsdXNoKClcbiAgaWYgKHRoaXMuX2F1dG9wYWRkaW5nKSB7XG4gICAgcmV0dXJuIHVucGFkKHRoaXMuX21vZGUuZGVjcnlwdCh0aGlzLCBjaHVuaykpXG4gIH0gZWxzZSBpZiAoY2h1bmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RhdGEgbm90IG11bHRpcGxlIG9mIGJsb2NrIGxlbmd0aCcpXG4gIH1cbn1cbkRlY2lwaGVyLnByb3RvdHlwZS5zZXRBdXRvUGFkZGluZyA9IGZ1bmN0aW9uIChzZXRUbykge1xuICB0aGlzLl9hdXRvcGFkZGluZyA9ICEhc2V0VG9cbiAgcmV0dXJuIHRoaXNcbn1cbmZ1bmN0aW9uIFNwbGl0dGVyICgpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNwbGl0dGVyKSkge1xuICAgIHJldHVybiBuZXcgU3BsaXR0ZXIoKVxuICB9XG4gIHRoaXMuY2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxufVxuU3BsaXR0ZXIucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuY2FjaGUgPSBCdWZmZXIuY29uY2F0KFt0aGlzLmNhY2hlLCBkYXRhXSlcbn1cblxuU3BsaXR0ZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChhdXRvUGFkZGluZykge1xuICB2YXIgb3V0XG4gIGlmIChhdXRvUGFkZGluZykge1xuICAgIGlmICh0aGlzLmNhY2hlLmxlbmd0aCA+IDE2KSB7XG4gICAgICBvdXQgPSB0aGlzLmNhY2hlLnNsaWNlKDAsIDE2KVxuICAgICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgICByZXR1cm4gb3V0XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmICh0aGlzLmNhY2hlLmxlbmd0aCA+PSAxNikge1xuICAgICAgb3V0ID0gdGhpcy5jYWNoZS5zbGljZSgwLCAxNilcbiAgICAgIHRoaXMuY2FjaGUgPSB0aGlzLmNhY2hlLnNsaWNlKDE2KVxuICAgICAgcmV0dXJuIG91dFxuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbFxufVxuU3BsaXR0ZXIucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jYWNoZS5sZW5ndGgpIHtcbiAgICByZXR1cm4gdGhpcy5jYWNoZVxuICB9XG59XG5mdW5jdGlvbiB1bnBhZCAobGFzdCkge1xuICB2YXIgcGFkZGVkID0gbGFzdFsxNV1cbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgcGFkZGVkKSB7XG4gICAgaWYgKGxhc3RbKGkgKyAoMTYgLSBwYWRkZWQpKV0gIT09IHBhZGRlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmFibGUgdG8gZGVjcnlwdCBkYXRhJylcbiAgICB9XG4gIH1cbiAgaWYgKHBhZGRlZCA9PT0gMTYpIHtcbiAgICByZXR1cm5cbiAgfVxuICByZXR1cm4gbGFzdC5zbGljZSgwLCAxNiAtIHBhZGRlZClcbn1cblxudmFyIG1vZGVsaXN0ID0ge1xuICBFQ0I6IHJlcXVpcmUoJy4vbW9kZXMvZWNiJyksXG4gIENCQzogcmVxdWlyZSgnLi9tb2Rlcy9jYmMnKSxcbiAgQ0ZCOiByZXF1aXJlKCcuL21vZGVzL2NmYicpLFxuICBDRkI4OiByZXF1aXJlKCcuL21vZGVzL2NmYjgnKSxcbiAgQ0ZCMTogcmVxdWlyZSgnLi9tb2Rlcy9jZmIxJyksXG4gIE9GQjogcmVxdWlyZSgnLi9tb2Rlcy9vZmInKSxcbiAgQ1RSOiByZXF1aXJlKCcuL21vZGVzL2N0cicpLFxuICBHQ006IHJlcXVpcmUoJy4vbW9kZXMvY3RyJylcbn1cblxuZnVuY3Rpb24gY3JlYXRlRGVjaXBoZXJpdiAoc3VpdGUsIHBhc3N3b3JkLCBpdikge1xuICB2YXIgY29uZmlnID0gbW9kZXNbc3VpdGUudG9Mb3dlckNhc2UoKV1cbiAgaWYgKCFjb25maWcpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuICB9XG4gIGlmICh0eXBlb2YgaXYgPT09ICdzdHJpbmcnKSB7XG4gICAgaXYgPSBuZXcgQnVmZmVyKGl2KVxuICB9XG4gIGlmICh0eXBlb2YgcGFzc3dvcmQgPT09ICdzdHJpbmcnKSB7XG4gICAgcGFzc3dvcmQgPSBuZXcgQnVmZmVyKHBhc3N3b3JkKVxuICB9XG4gIGlmIChwYXNzd29yZC5sZW5ndGggIT09IGNvbmZpZy5rZXkgLyA4KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBrZXkgbGVuZ3RoICcgKyBwYXNzd29yZC5sZW5ndGgpXG4gIH1cbiAgaWYgKGl2Lmxlbmd0aCAhPT0gY29uZmlnLml2KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBpdiBsZW5ndGggJyArIGl2Lmxlbmd0aClcbiAgfVxuICBpZiAoY29uZmlnLnR5cGUgPT09ICdzdHJlYW0nKSB7XG4gICAgcmV0dXJuIG5ldyBTdHJlYW1DaXBoZXIobW9kZWxpc3RbY29uZmlnLm1vZGVdLCBwYXNzd29yZCwgaXYsIHRydWUpXG4gIH0gZWxzZSBpZiAoY29uZmlnLnR5cGUgPT09ICdhdXRoJykge1xuICAgIHJldHVybiBuZXcgQXV0aENpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdiwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gbmV3IERlY2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2KVxufVxuXG5mdW5jdGlvbiBjcmVhdGVEZWNpcGhlciAoc3VpdGUsIHBhc3N3b3JkKSB7XG4gIHZhciBjb25maWcgPSBtb2Rlc1tzdWl0ZS50b0xvd2VyQ2FzZSgpXVxuICBpZiAoIWNvbmZpZykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgdmFyIGtleXMgPSBlYnRrKHBhc3N3b3JkLCBmYWxzZSwgY29uZmlnLmtleSwgY29uZmlnLml2KVxuICByZXR1cm4gY3JlYXRlRGVjaXBoZXJpdihzdWl0ZSwga2V5cy5rZXksIGtleXMuaXYpXG59XG5leHBvcnRzLmNyZWF0ZURlY2lwaGVyID0gY3JlYXRlRGVjaXBoZXJcbmV4cG9ydHMuY3JlYXRlRGVjaXBoZXJpdiA9IGNyZWF0ZURlY2lwaGVyaXZcbiIsInZhciBhZXMgPSByZXF1aXJlKCcuL2FlcycpXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIG1vZGVzID0gcmVxdWlyZSgnLi9tb2RlcycpXG52YXIgZWJ0ayA9IHJlcXVpcmUoJ2V2cF9ieXRlc3Rva2V5JylcbnZhciBTdHJlYW1DaXBoZXIgPSByZXF1aXJlKCcuL3N0cmVhbUNpcGhlcicpXG52YXIgQXV0aENpcGhlciA9IHJlcXVpcmUoJy4vYXV0aENpcGhlcicpXG5pbmhlcml0cyhDaXBoZXIsIFRyYW5zZm9ybSlcbmZ1bmN0aW9uIENpcGhlciAobW9kZSwga2V5LCBpdikge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQ2lwaGVyKSkge1xuICAgIHJldHVybiBuZXcgQ2lwaGVyKG1vZGUsIGtleSwgaXYpXG4gIH1cbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5fY2FjaGUgPSBuZXcgU3BsaXR0ZXIoKVxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHRoaXMuX3ByZXYgPSBuZXcgQnVmZmVyKGl2Lmxlbmd0aClcbiAgaXYuY29weSh0aGlzLl9wcmV2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxuICB0aGlzLl9hdXRvcGFkZGluZyA9IHRydWVcbn1cbkNpcGhlci5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuX2NhY2hlLmFkZChkYXRhKVxuICB2YXIgY2h1bmtcbiAgdmFyIHRoaW5nXG4gIHZhciBvdXQgPSBbXVxuICB3aGlsZSAoKGNodW5rID0gdGhpcy5fY2FjaGUuZ2V0KCkpKSB7XG4gICAgdGhpbmcgPSB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmspXG4gICAgb3V0LnB1c2godGhpbmcpXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5jb25jYXQob3V0KVxufVxuQ2lwaGVyLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBjaHVuayA9IHRoaXMuX2NhY2hlLmZsdXNoKClcbiAgaWYgKHRoaXMuX2F1dG9wYWRkaW5nKSB7XG4gICAgY2h1bmsgPSB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmspXG4gICAgdGhpcy5fY2lwaGVyLnNjcnViKClcbiAgICByZXR1cm4gY2h1bmtcbiAgfSBlbHNlIGlmIChjaHVuay50b1N0cmluZygnaGV4JykgIT09ICcxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMCcpIHtcbiAgICB0aGlzLl9jaXBoZXIuc2NydWIoKVxuICAgIHRocm93IG5ldyBFcnJvcignZGF0YSBub3QgbXVsdGlwbGUgb2YgYmxvY2sgbGVuZ3RoJylcbiAgfVxufVxuQ2lwaGVyLnByb3RvdHlwZS5zZXRBdXRvUGFkZGluZyA9IGZ1bmN0aW9uIChzZXRUbykge1xuICB0aGlzLl9hdXRvcGFkZGluZyA9ICEhc2V0VG9cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gU3BsaXR0ZXIgKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3BsaXR0ZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBTcGxpdHRlcigpXG4gIH1cbiAgdGhpcy5jYWNoZSA9IG5ldyBCdWZmZXIoJycpXG59XG5TcGxpdHRlci5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIGRhdGFdKVxufVxuXG5TcGxpdHRlci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jYWNoZS5sZW5ndGggPiAxNSkge1xuICAgIHZhciBvdXQgPSB0aGlzLmNhY2hlLnNsaWNlKDAsIDE2KVxuICAgIHRoaXMuY2FjaGUgPSB0aGlzLmNhY2hlLnNsaWNlKDE2KVxuICAgIHJldHVybiBvdXRcbiAgfVxuICByZXR1cm4gbnVsbFxufVxuU3BsaXR0ZXIucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbGVuID0gMTYgLSB0aGlzLmNhY2hlLmxlbmd0aFxuICB2YXIgcGFkQnVmZiA9IG5ldyBCdWZmZXIobGVuKVxuXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIHBhZEJ1ZmYud3JpdGVVSW50OChsZW4sIGkpXG4gIH1cbiAgdmFyIG91dCA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIHBhZEJ1ZmZdKVxuICByZXR1cm4gb3V0XG59XG52YXIgbW9kZWxpc3QgPSB7XG4gIEVDQjogcmVxdWlyZSgnLi9tb2Rlcy9lY2InKSxcbiAgQ0JDOiByZXF1aXJlKCcuL21vZGVzL2NiYycpLFxuICBDRkI6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiJyksXG4gIENGQjg6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiOCcpLFxuICBDRkIxOiByZXF1aXJlKCcuL21vZGVzL2NmYjEnKSxcbiAgT0ZCOiByZXF1aXJlKCcuL21vZGVzL29mYicpLFxuICBDVFI6IHJlcXVpcmUoJy4vbW9kZXMvY3RyJyksXG4gIEdDTTogcmVxdWlyZSgnLi9tb2Rlcy9jdHInKVxufVxuXG5mdW5jdGlvbiBjcmVhdGVDaXBoZXJpdiAoc3VpdGUsIHBhc3N3b3JkLCBpdikge1xuICB2YXIgY29uZmlnID0gbW9kZXNbc3VpdGUudG9Mb3dlckNhc2UoKV1cbiAgaWYgKCFjb25maWcpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuICB9XG4gIGlmICh0eXBlb2YgaXYgPT09ICdzdHJpbmcnKSB7XG4gICAgaXYgPSBuZXcgQnVmZmVyKGl2KVxuICB9XG4gIGlmICh0eXBlb2YgcGFzc3dvcmQgPT09ICdzdHJpbmcnKSB7XG4gICAgcGFzc3dvcmQgPSBuZXcgQnVmZmVyKHBhc3N3b3JkKVxuICB9XG4gIGlmIChwYXNzd29yZC5sZW5ndGggIT09IGNvbmZpZy5rZXkgLyA4KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBrZXkgbGVuZ3RoICcgKyBwYXNzd29yZC5sZW5ndGgpXG4gIH1cbiAgaWYgKGl2Lmxlbmd0aCAhPT0gY29uZmlnLml2KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBpdiBsZW5ndGggJyArIGl2Lmxlbmd0aClcbiAgfVxuICBpZiAoY29uZmlnLnR5cGUgPT09ICdzdHJlYW0nKSB7XG4gICAgcmV0dXJuIG5ldyBTdHJlYW1DaXBoZXIobW9kZWxpc3RbY29uZmlnLm1vZGVdLCBwYXNzd29yZCwgaXYpXG4gIH0gZWxzZSBpZiAoY29uZmlnLnR5cGUgPT09ICdhdXRoJykge1xuICAgIHJldHVybiBuZXcgQXV0aENpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdilcbiAgfVxuICByZXR1cm4gbmV3IENpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdilcbn1cbmZ1bmN0aW9uIGNyZWF0ZUNpcGhlciAoc3VpdGUsIHBhc3N3b3JkKSB7XG4gIHZhciBjb25maWcgPSBtb2Rlc1tzdWl0ZS50b0xvd2VyQ2FzZSgpXVxuICBpZiAoIWNvbmZpZykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgdmFyIGtleXMgPSBlYnRrKHBhc3N3b3JkLCBmYWxzZSwgY29uZmlnLmtleSwgY29uZmlnLml2KVxuICByZXR1cm4gY3JlYXRlQ2lwaGVyaXYoc3VpdGUsIGtleXMua2V5LCBrZXlzLml2KVxufVxuXG5leHBvcnRzLmNyZWF0ZUNpcGhlcml2ID0gY3JlYXRlQ2lwaGVyaXZcbmV4cG9ydHMuY3JlYXRlQ2lwaGVyID0gY3JlYXRlQ2lwaGVyXG4iLCJ2YXIgemVyb3MgPSBuZXcgQnVmZmVyKDE2KVxuemVyb3MuZmlsbCgwKVxubW9kdWxlLmV4cG9ydHMgPSBHSEFTSFxuZnVuY3Rpb24gR0hBU0ggKGtleSkge1xuICB0aGlzLmggPSBrZXlcbiAgdGhpcy5zdGF0ZSA9IG5ldyBCdWZmZXIoMTYpXG4gIHRoaXMuc3RhdGUuZmlsbCgwKVxuICB0aGlzLmNhY2hlID0gbmV3IEJ1ZmZlcignJylcbn1cbi8vIGZyb20gaHR0cDovL2JpdHdpc2VzaGlmdGxlZnQuZ2l0aHViLmlvL3NqY2wvZG9jL3N5bWJvbHMvc3JjL2NvcmVfZ2NtLmpzLmh0bWxcbi8vIGJ5IEp1aG8gVsOkaMOkLUhlcnR0dWFcbkdIQVNILnByb3RvdHlwZS5naGFzaCA9IGZ1bmN0aW9uIChibG9jaykge1xuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBibG9jay5sZW5ndGgpIHtcbiAgICB0aGlzLnN0YXRlW2ldIF49IGJsb2NrW2ldXG4gIH1cbiAgdGhpcy5fbXVsdGlwbHkoKVxufVxuXG5HSEFTSC5wcm90b3R5cGUuX211bHRpcGx5ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgVmkgPSB0b0FycmF5KHRoaXMuaClcbiAgdmFyIFppID0gWzAsIDAsIDAsIDBdXG4gIHZhciBqLCB4aSwgbHNiX1ZpXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IDEyOCkge1xuICAgIHhpID0gKHRoaXMuc3RhdGVbfn4oaSAvIDgpXSAmICgxIDw8ICg3IC0gaSAlIDgpKSkgIT09IDBcbiAgICBpZiAoeGkpIHtcbiAgICAgIC8vIFpfaSsxID0gWl9pIF4gVl9pXG4gICAgICBaaSA9IHhvcihaaSwgVmkpXG4gICAgfVxuXG4gICAgLy8gU3RvcmUgdGhlIHZhbHVlIG9mIExTQihWX2kpXG4gICAgbHNiX1ZpID0gKFZpWzNdICYgMSkgIT09IDBcblxuICAgIC8vIFZfaSsxID0gVl9pID4+IDFcbiAgICBmb3IgKGogPSAzOyBqID4gMDsgai0tKSB7XG4gICAgICBWaVtqXSA9IChWaVtqXSA+Pj4gMSkgfCAoKFZpW2ogLSAxXSAmIDEpIDw8IDMxKVxuICAgIH1cbiAgICBWaVswXSA9IFZpWzBdID4+PiAxXG5cbiAgICAvLyBJZiBMU0IoVl9pKSBpcyAxLCBWX2krMSA9IChWX2kgPj4gMSkgXiBSXG4gICAgaWYgKGxzYl9WaSkge1xuICAgICAgVmlbMF0gPSBWaVswXSBeICgweGUxIDw8IDI0KVxuICAgIH1cbiAgfVxuICB0aGlzLnN0YXRlID0gZnJvbUFycmF5KFppKVxufVxuR0hBU0gucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChidWYpIHtcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIGJ1Zl0pXG4gIHZhciBjaHVua1xuICB3aGlsZSAodGhpcy5jYWNoZS5sZW5ndGggPj0gMTYpIHtcbiAgICBjaHVuayA9IHRoaXMuY2FjaGUuc2xpY2UoMCwgMTYpXG4gICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgdGhpcy5naGFzaChjaHVuaylcbiAgfVxufVxuR0hBU0gucHJvdG90eXBlLmZpbmFsID0gZnVuY3Rpb24gKGFibCwgYmwpIHtcbiAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoKSB7XG4gICAgdGhpcy5naGFzaChCdWZmZXIuY29uY2F0KFt0aGlzLmNhY2hlLCB6ZXJvc10sIDE2KSlcbiAgfVxuICB0aGlzLmdoYXNoKGZyb21BcnJheShbXG4gICAgMCwgYWJsLFxuICAgIDAsIGJsXG4gIF0pKVxuICByZXR1cm4gdGhpcy5zdGF0ZVxufVxuXG5mdW5jdGlvbiB0b0FycmF5IChidWYpIHtcbiAgcmV0dXJuIFtcbiAgICBidWYucmVhZFVJbnQzMkJFKDApLFxuICAgIGJ1Zi5yZWFkVUludDMyQkUoNCksXG4gICAgYnVmLnJlYWRVSW50MzJCRSg4KSxcbiAgICBidWYucmVhZFVJbnQzMkJFKDEyKVxuICBdXG59XG5mdW5jdGlvbiBmcm9tQXJyYXkgKG91dCkge1xuICBvdXQgPSBvdXQubWFwKGZpeHVwX3VpbnQzMilcbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoMTYpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFswXSwgMClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzFdLCA0KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMl0sIDgpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFszXSwgMTIpXG4gIHJldHVybiBidWZcbn1cbnZhciB1aW50X21heCA9IE1hdGgucG93KDIsIDMyKVxuZnVuY3Rpb24gZml4dXBfdWludDMyICh4KSB7XG4gIHZhciByZXQsIHhfcG9zXG4gIHJldCA9IHggPiB1aW50X21heCB8fCB4IDwgMCA/ICh4X3BvcyA9IE1hdGguYWJzKHgpICUgdWludF9tYXgsIHggPCAwID8gdWludF9tYXggLSB4X3BvcyA6IHhfcG9zKSA6IHhcbiAgcmV0dXJuIHJldFxufVxuZnVuY3Rpb24geG9yIChhLCBiKSB7XG4gIHJldHVybiBbXG4gICAgYVswXSBeIGJbMF0sXG4gICAgYVsxXSBeIGJbMV0sXG4gICAgYVsyXSBeIGJbMl0sXG4gICAgYVszXSBeIGJbM11cbiAgXVxufVxuIiwiZXhwb3J0c1snYWVzLTEyOC1lY2InXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxMjgsXG4gIGl2OiAwLFxuICBtb2RlOiAnRUNCJyxcbiAgdHlwZTogJ2Jsb2NrJ1xufVxuZXhwb3J0c1snYWVzLTE5Mi1lY2InXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxOTIsXG4gIGl2OiAwLFxuICBtb2RlOiAnRUNCJyxcbiAgdHlwZTogJ2Jsb2NrJ1xufVxuZXhwb3J0c1snYWVzLTI1Ni1lY2InXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAyNTYsXG4gIGl2OiAwLFxuICBtb2RlOiAnRUNCJyxcbiAgdHlwZTogJ2Jsb2NrJ1xufVxuZXhwb3J0c1snYWVzLTEyOC1jYmMnXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxMjgsXG4gIGl2OiAxNixcbiAgbW9kZTogJ0NCQycsXG4gIHR5cGU6ICdibG9jaydcbn1cbmV4cG9ydHNbJ2Flcy0xOTItY2JjJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMTkyLFxuICBpdjogMTYsXG4gIG1vZGU6ICdDQkMnLFxuICB0eXBlOiAnYmxvY2snXG59XG5leHBvcnRzWydhZXMtMjU2LWNiYyddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDI1NixcbiAgaXY6IDE2LFxuICBtb2RlOiAnQ0JDJyxcbiAgdHlwZTogJ2Jsb2NrJ1xufVxuZXhwb3J0c1snYWVzMTI4J10gPSBleHBvcnRzWydhZXMtMTI4LWNiYyddXG5leHBvcnRzWydhZXMxOTInXSA9IGV4cG9ydHNbJ2Flcy0xOTItY2JjJ11cbmV4cG9ydHNbJ2FlczI1NiddID0gZXhwb3J0c1snYWVzLTI1Ni1jYmMnXVxuZXhwb3J0c1snYWVzLTEyOC1jZmInXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxMjgsXG4gIGl2OiAxNixcbiAgbW9kZTogJ0NGQicsXG4gIHR5cGU6ICdzdHJlYW0nXG59XG5leHBvcnRzWydhZXMtMTkyLWNmYiddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDE5MixcbiAgaXY6IDE2LFxuICBtb2RlOiAnQ0ZCJyxcbiAgdHlwZTogJ3N0cmVhbSdcbn1cbmV4cG9ydHNbJ2Flcy0yNTYtY2ZiJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMjU2LFxuICBpdjogMTYsXG4gIG1vZGU6ICdDRkInLFxuICB0eXBlOiAnc3RyZWFtJ1xufVxuZXhwb3J0c1snYWVzLTEyOC1jZmI4J10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMTI4LFxuICBpdjogMTYsXG4gIG1vZGU6ICdDRkI4JyxcbiAgdHlwZTogJ3N0cmVhbSdcbn1cbmV4cG9ydHNbJ2Flcy0xOTItY2ZiOCddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDE5MixcbiAgaXY6IDE2LFxuICBtb2RlOiAnQ0ZCOCcsXG4gIHR5cGU6ICdzdHJlYW0nXG59XG5leHBvcnRzWydhZXMtMjU2LWNmYjgnXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAyNTYsXG4gIGl2OiAxNixcbiAgbW9kZTogJ0NGQjgnLFxuICB0eXBlOiAnc3RyZWFtJ1xufVxuZXhwb3J0c1snYWVzLTEyOC1jZmIxJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMTI4LFxuICBpdjogMTYsXG4gIG1vZGU6ICdDRkIxJyxcbiAgdHlwZTogJ3N0cmVhbSdcbn1cbmV4cG9ydHNbJ2Flcy0xOTItY2ZiMSddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDE5MixcbiAgaXY6IDE2LFxuICBtb2RlOiAnQ0ZCMScsXG4gIHR5cGU6ICdzdHJlYW0nXG59XG5leHBvcnRzWydhZXMtMjU2LWNmYjEnXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAyNTYsXG4gIGl2OiAxNixcbiAgbW9kZTogJ0NGQjEnLFxuICB0eXBlOiAnc3RyZWFtJ1xufVxuZXhwb3J0c1snYWVzLTEyOC1vZmInXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxMjgsXG4gIGl2OiAxNixcbiAgbW9kZTogJ09GQicsXG4gIHR5cGU6ICdzdHJlYW0nXG59XG5leHBvcnRzWydhZXMtMTkyLW9mYiddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDE5MixcbiAgaXY6IDE2LFxuICBtb2RlOiAnT0ZCJyxcbiAgdHlwZTogJ3N0cmVhbSdcbn1cbmV4cG9ydHNbJ2Flcy0yNTYtb2ZiJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMjU2LFxuICBpdjogMTYsXG4gIG1vZGU6ICdPRkInLFxuICB0eXBlOiAnc3RyZWFtJ1xufVxuZXhwb3J0c1snYWVzLTEyOC1jdHInXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxMjgsXG4gIGl2OiAxNixcbiAgbW9kZTogJ0NUUicsXG4gIHR5cGU6ICdzdHJlYW0nXG59XG5leHBvcnRzWydhZXMtMTkyLWN0ciddID0ge1xuICBjaXBoZXI6ICdBRVMnLFxuICBrZXk6IDE5MixcbiAgaXY6IDE2LFxuICBtb2RlOiAnQ1RSJyxcbiAgdHlwZTogJ3N0cmVhbSdcbn1cbmV4cG9ydHNbJ2Flcy0yNTYtY3RyJ10gPSB7XG4gIGNpcGhlcjogJ0FFUycsXG4gIGtleTogMjU2LFxuICBpdjogMTYsXG4gIG1vZGU6ICdDVFInLFxuICB0eXBlOiAnc3RyZWFtJ1xufVxuZXhwb3J0c1snYWVzLTEyOC1nY20nXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxMjgsXG4gIGl2OiAxMixcbiAgbW9kZTogJ0dDTScsXG4gIHR5cGU6ICdhdXRoJ1xufVxuZXhwb3J0c1snYWVzLTE5Mi1nY20nXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAxOTIsXG4gIGl2OiAxMixcbiAgbW9kZTogJ0dDTScsXG4gIHR5cGU6ICdhdXRoJ1xufVxuZXhwb3J0c1snYWVzLTI1Ni1nY20nXSA9IHtcbiAgY2lwaGVyOiAnQUVTJyxcbiAga2V5OiAyNTYsXG4gIGl2OiAxMixcbiAgbW9kZTogJ0dDTScsXG4gIHR5cGU6ICdhdXRoJ1xufVxuIiwidmFyIHhvciA9IHJlcXVpcmUoJ2J1ZmZlci14b3InKVxuXG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgYmxvY2spIHtcbiAgdmFyIGRhdGEgPSB4b3IoYmxvY2ssIHNlbGYuX3ByZXYpXG5cbiAgc2VsZi5fcHJldiA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soZGF0YSlcbiAgcmV0dXJuIHNlbGYuX3ByZXZcbn1cblxuZXhwb3J0cy5kZWNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGJsb2NrKSB7XG4gIHZhciBwYWQgPSBzZWxmLl9wcmV2XG5cbiAgc2VsZi5fcHJldiA9IGJsb2NrXG4gIHZhciBvdXQgPSBzZWxmLl9jaXBoZXIuZGVjcnlwdEJsb2NrKGJsb2NrKVxuXG4gIHJldHVybiB4b3Iob3V0LCBwYWQpXG59XG4iLCJ2YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG5cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBkYXRhLCBkZWNyeXB0KSB7XG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKCcnKVxuICB2YXIgbGVuXG5cbiAgd2hpbGUgKGRhdGEubGVuZ3RoKSB7XG4gICAgaWYgKHNlbGYuX2NhY2hlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gICAgICBzZWxmLl9wcmV2ID0gbmV3IEJ1ZmZlcignJylcbiAgICB9XG5cbiAgICBpZiAoc2VsZi5fY2FjaGUubGVuZ3RoIDw9IGRhdGEubGVuZ3RoKSB7XG4gICAgICBsZW4gPSBzZWxmLl9jYWNoZS5sZW5ndGhcbiAgICAgIG91dCA9IEJ1ZmZlci5jb25jYXQoW291dCwgZW5jcnlwdFN0YXJ0KHNlbGYsIGRhdGEuc2xpY2UoMCwgbGVuKSwgZGVjcnlwdCldKVxuICAgICAgZGF0YSA9IGRhdGEuc2xpY2UobGVuKVxuICAgIH0gZWxzZSB7XG4gICAgICBvdXQgPSBCdWZmZXIuY29uY2F0KFtvdXQsIGVuY3J5cHRTdGFydChzZWxmLCBkYXRhLCBkZWNyeXB0KV0pXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvdXRcbn1cbmZ1bmN0aW9uIGVuY3J5cHRTdGFydCAoc2VsZiwgZGF0YSwgZGVjcnlwdCkge1xuICB2YXIgbGVuID0gZGF0YS5sZW5ndGhcbiAgdmFyIG91dCA9IHhvcihkYXRhLCBzZWxmLl9jYWNoZSlcbiAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jYWNoZS5zbGljZShsZW4pXG4gIHNlbGYuX3ByZXYgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9wcmV2LCBkZWNyeXB0ID8gZGF0YSA6IG91dF0pXG4gIHJldHVybiBvdXRcbn1cbiIsImZ1bmN0aW9uIGVuY3J5cHRCeXRlIChzZWxmLCBieXRlUGFyYW0sIGRlY3J5cHQpIHtcbiAgdmFyIHBhZFxuICB2YXIgaSA9IC0xXG4gIHZhciBsZW4gPSA4XG4gIHZhciBvdXQgPSAwXG4gIHZhciBiaXQsIHZhbHVlXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBwYWQgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gICAgYml0ID0gKGJ5dGVQYXJhbSAmICgxIDw8ICg3IC0gaSkpKSA/IDB4ODAgOiAwXG4gICAgdmFsdWUgPSBwYWRbMF0gXiBiaXRcbiAgICBvdXQgKz0gKCh2YWx1ZSAmIDB4ODApID4+IChpICUgOCkpXG4gICAgc2VsZi5fcHJldiA9IHNoaWZ0SW4oc2VsZi5fcHJldiwgZGVjcnlwdCA/IGJpdCA6IHZhbHVlKVxuICB9XG4gIHJldHVybiBvdXRcbn1cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBjaHVuaywgZGVjcnlwdCkge1xuICB2YXIgbGVuID0gY2h1bmsubGVuZ3RoXG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKGxlbilcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgb3V0W2ldID0gZW5jcnlwdEJ5dGUoc2VsZiwgY2h1bmtbaV0sIGRlY3J5cHQpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuZnVuY3Rpb24gc2hpZnRJbiAoYnVmZmVyLCB2YWx1ZSkge1xuICB2YXIgbGVuID0gYnVmZmVyLmxlbmd0aFxuICB2YXIgaSA9IC0xXG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKGJ1ZmZlci5sZW5ndGgpXG4gIGJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoW2J1ZmZlciwgbmV3IEJ1ZmZlcihbdmFsdWVdKV0pXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXRbaV0gPSBidWZmZXJbaV0gPDwgMSB8IGJ1ZmZlcltpICsgMV0gPj4gKDcpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwiZnVuY3Rpb24gZW5jcnlwdEJ5dGUgKHNlbGYsIGJ5dGVQYXJhbSwgZGVjcnlwdCkge1xuICB2YXIgcGFkID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhzZWxmLl9wcmV2KVxuICB2YXIgb3V0ID0gcGFkWzBdIF4gYnl0ZVBhcmFtXG4gIHNlbGYuX3ByZXYgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9wcmV2LnNsaWNlKDEpLCBuZXcgQnVmZmVyKFtkZWNyeXB0ID8gYnl0ZVBhcmFtIDogb3V0XSldKVxuICByZXR1cm4gb3V0XG59XG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgY2h1bmssIGRlY3J5cHQpIHtcbiAgdmFyIGxlbiA9IGNodW5rLmxlbmd0aFxuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihsZW4pXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dFtpXSA9IGVuY3J5cHRCeXRlKHNlbGYsIGNodW5rW2ldLCBkZWNyeXB0KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsInZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcblxuZnVuY3Rpb24gaW5jcjMyIChpdikge1xuICB2YXIgbGVuID0gaXYubGVuZ3RoXG4gIHZhciBpdGVtXG4gIHdoaWxlIChsZW4tLSkge1xuICAgIGl0ZW0gPSBpdi5yZWFkVUludDgobGVuKVxuICAgIGlmIChpdGVtID09PSAyNTUpIHtcbiAgICAgIGl2LndyaXRlVUludDgoMCwgbGVuKVxuICAgIH0gZWxzZSB7XG4gICAgICBpdGVtKytcbiAgICAgIGl2LndyaXRlVUludDgoaXRlbSwgbGVuKVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0QmxvY2sgKHNlbGYpIHtcbiAgdmFyIG91dCA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soc2VsZi5fcHJldilcbiAgaW5jcjMyKHNlbGYuX3ByZXYpXG4gIHJldHVybiBvdXRcbn1cblxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGNodW5rKSB7XG4gIHdoaWxlIChzZWxmLl9jYWNoZS5sZW5ndGggPCBjaHVuay5sZW5ndGgpIHtcbiAgICBzZWxmLl9jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3NlbGYuX2NhY2hlLCBnZXRCbG9jayhzZWxmKV0pXG4gIH1cbiAgdmFyIHBhZCA9IHNlbGYuX2NhY2hlLnNsaWNlKDAsIGNodW5rLmxlbmd0aClcbiAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jYWNoZS5zbGljZShjaHVuay5sZW5ndGgpXG4gIHJldHVybiB4b3IoY2h1bmssIHBhZClcbn1cbiIsImV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBibG9jaykge1xuICByZXR1cm4gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhibG9jaylcbn1cbmV4cG9ydHMuZGVjcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBibG9jaykge1xuICByZXR1cm4gc2VsZi5fY2lwaGVyLmRlY3J5cHRCbG9jayhibG9jaylcbn1cbiIsInZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcblxuZnVuY3Rpb24gZ2V0QmxvY2sgKHNlbGYpIHtcbiAgc2VsZi5fcHJldiA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soc2VsZi5fcHJldilcbiAgcmV0dXJuIHNlbGYuX3ByZXZcbn1cblxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGNodW5rKSB7XG4gIHdoaWxlIChzZWxmLl9jYWNoZS5sZW5ndGggPCBjaHVuay5sZW5ndGgpIHtcbiAgICBzZWxmLl9jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3NlbGYuX2NhY2hlLCBnZXRCbG9jayhzZWxmKV0pXG4gIH1cblxuICB2YXIgcGFkID0gc2VsZi5fY2FjaGUuc2xpY2UoMCwgY2h1bmsubGVuZ3RoKVxuICBzZWxmLl9jYWNoZSA9IHNlbGYuX2NhY2hlLnNsaWNlKGNodW5rLmxlbmd0aClcbiAgcmV0dXJuIHhvcihjaHVuaywgcGFkKVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB4b3IgKGEsIGIpIHtcbiAgdmFyIGxlbmd0aCA9IE1hdGgubWluKGEubGVuZ3RoLCBiLmxlbmd0aClcbiAgdmFyIGJ1ZmZlciA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBidWZmZXJbaV0gPSBhW2ldIF4gYltpXVxuICB9XG5cbiAgcmV0dXJuIGJ1ZmZlclxufVxuIiwidmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ3N0cmVhbScpLlRyYW5zZm9ybVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2RlcicpLlN0cmluZ0RlY29kZXJcbm1vZHVsZS5leHBvcnRzID0gQ2lwaGVyQmFzZVxuaW5oZXJpdHMoQ2lwaGVyQmFzZSwgVHJhbnNmb3JtKVxuZnVuY3Rpb24gQ2lwaGVyQmFzZSAoaGFzaE1vZGUpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5oYXNoTW9kZSA9IHR5cGVvZiBoYXNoTW9kZSA9PT0gJ3N0cmluZydcbiAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICB0aGlzW2hhc2hNb2RlXSA9IHRoaXMuX2ZpbmFsT3JEaWdlc3RcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmZpbmFsID0gdGhpcy5fZmluYWxPckRpZ2VzdFxuICB9XG4gIHRoaXMuX2RlY29kZXIgPSBudWxsXG4gIHRoaXMuX2VuY29kaW5nID0gbnVsbFxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGlucHV0RW5jLCBvdXRwdXRFbmMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIGRhdGEgPSBuZXcgQnVmZmVyKGRhdGEsIGlucHV0RW5jKVxuICB9XG4gIHZhciBvdXREYXRhID0gdGhpcy5fdXBkYXRlKGRhdGEpXG4gIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuICBpZiAob3V0cHV0RW5jKSB7XG4gICAgb3V0RGF0YSA9IHRoaXMuX3RvU3RyaW5nKG91dERhdGEsIG91dHB1dEVuYylcbiAgfVxuICByZXR1cm4gb3V0RGF0YVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBdXRvUGFkZGluZyA9IGZ1bmN0aW9uICgpIHt9XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIHNldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEFBRCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gc2V0IGFhZCBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoZGF0YSwgXywgbmV4dCkge1xuICB2YXIgZXJyXG4gIHRyeSB7XG4gICAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZShkYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnB1c2godGhpcy5fdXBkYXRlKGRhdGEpKVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfSBmaW5hbGx5IHtcbiAgICBuZXh0KGVycilcbiAgfVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZsdXNoID0gZnVuY3Rpb24gKGRvbmUpIHtcbiAgdmFyIGVyclxuICB0cnkge1xuICAgIHRoaXMucHVzaCh0aGlzLl9maW5hbCgpKVxuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyID0gZVxuICB9IGZpbmFsbHkge1xuICAgIGRvbmUoZXJyKVxuICB9XG59XG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fZmluYWxPckRpZ2VzdCA9IGZ1bmN0aW9uIChvdXRwdXRFbmMpIHtcbiAgdmFyIG91dERhdGEgPSB0aGlzLl9maW5hbCgpIHx8IG5ldyBCdWZmZXIoJycpXG4gIGlmIChvdXRwdXRFbmMpIHtcbiAgICBvdXREYXRhID0gdGhpcy5fdG9TdHJpbmcob3V0RGF0YSwgb3V0cHV0RW5jLCB0cnVlKVxuICB9XG4gIHJldHVybiBvdXREYXRhXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90b1N0cmluZyA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jLCBmaW5hbCkge1xuICBpZiAoIXRoaXMuX2RlY29kZXIpIHtcbiAgICB0aGlzLl9kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKVxuICAgIHRoaXMuX2VuY29kaW5nID0gZW5jXG4gIH1cbiAgaWYgKHRoaXMuX2VuY29kaW5nICE9PSBlbmMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NhblxcJ3Qgc3dpdGNoIGVuY29kaW5ncycpXG4gIH1cbiAgdmFyIG91dCA9IHRoaXMuX2RlY29kZXIud3JpdGUodmFsdWUpXG4gIGlmIChmaW5hbCkge1xuICAgIG91dCArPSB0aGlzLl9kZWNvZGVyLmVuZCgpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG5cbmluaGVyaXRzKFN0cmVhbUNpcGhlciwgVHJhbnNmb3JtKVxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW1DaXBoZXJcbmZ1bmN0aW9uIFN0cmVhbUNpcGhlciAobW9kZSwga2V5LCBpdiwgZGVjcnlwdCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3RyZWFtQ2lwaGVyKSkge1xuICAgIHJldHVybiBuZXcgU3RyZWFtQ2lwaGVyKG1vZGUsIGtleSwgaXYpXG4gIH1cbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5fY2lwaGVyID0gbmV3IGFlcy5BRVMoa2V5KVxuICB0aGlzLl9wcmV2ID0gbmV3IEJ1ZmZlcihpdi5sZW5ndGgpXG4gIHRoaXMuX2NhY2hlID0gbmV3IEJ1ZmZlcignJylcbiAgdGhpcy5fc2VjQ2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxuICB0aGlzLl9kZWNyeXB0ID0gZGVjcnlwdFxuICBpdi5jb3B5KHRoaXMuX3ByZXYpXG4gIHRoaXMuX21vZGUgPSBtb2RlXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgcmV0dXJuIHRoaXMuX21vZGUuZW5jcnlwdCh0aGlzLCBjaHVuaywgdGhpcy5fZGVjcnlwdClcbn1cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9jaXBoZXIuc2NydWIoKVxufVxuIiwidmFyIENpcGhlckJhc2UgPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgZGVzID0gcmVxdWlyZSgnZGVzLmpzJylcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcblxudmFyIG1vZGVzID0ge1xuICAnZGVzLWVkZTMtY2JjJzogZGVzLkNCQy5pbnN0YW50aWF0ZShkZXMuRURFKSxcbiAgJ2Rlcy1lZGUzJzogZGVzLkVERSxcbiAgJ2Rlcy1lZGUtY2JjJzogZGVzLkNCQy5pbnN0YW50aWF0ZShkZXMuRURFKSxcbiAgJ2Rlcy1lZGUnOiBkZXMuRURFLFxuICAnZGVzLWNiYyc6IGRlcy5DQkMuaW5zdGFudGlhdGUoZGVzLkRFUyksXG4gICdkZXMtZWNiJzogZGVzLkRFU1xufVxubW9kZXMuZGVzID0gbW9kZXNbJ2Rlcy1jYmMnXVxubW9kZXMuZGVzMyA9IG1vZGVzWydkZXMtZWRlMy1jYmMnXVxubW9kdWxlLmV4cG9ydHMgPSBERVNcbmluaGVyaXRzKERFUywgQ2lwaGVyQmFzZSlcbmZ1bmN0aW9uIERFUyAob3B0cykge1xuICBDaXBoZXJCYXNlLmNhbGwodGhpcylcbiAgdmFyIG1vZGVOYW1lID0gb3B0cy5tb2RlLnRvTG93ZXJDYXNlKClcbiAgdmFyIG1vZGUgPSBtb2Rlc1ttb2RlTmFtZV1cbiAgdmFyIHR5cGVcbiAgaWYgKG9wdHMuZGVjcnlwdCkge1xuICAgIHR5cGUgPSAnZGVjcnlwdCdcbiAgfSBlbHNlIHtcbiAgICB0eXBlID0gJ2VuY3J5cHQnXG4gIH1cbiAgdmFyIGtleSA9IG9wdHMua2V5XG4gIGlmIChtb2RlTmFtZSA9PT0gJ2Rlcy1lZGUnIHx8IG1vZGVOYW1lID09PSAnZGVzLWVkZS1jYmMnKSB7XG4gICAga2V5ID0gQnVmZmVyLmNvbmNhdChba2V5LCBrZXkuc2xpY2UoMCwgOCldKVxuICB9XG4gIHZhciBpdiA9IG9wdHMuaXZcbiAgdGhpcy5fZGVzID0gbW9kZS5jcmVhdGUoe1xuICAgIGtleToga2V5LFxuICAgIGl2OiBpdixcbiAgICB0eXBlOiB0eXBlXG4gIH0pXG59XG5ERVMucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSkge1xuICByZXR1cm4gbmV3IEJ1ZmZlcih0aGlzLl9kZXMudXBkYXRlKGRhdGEpKVxufVxuREVTLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBuZXcgQnVmZmVyKHRoaXMuX2Rlcy5maW5hbCgpKVxufVxuIiwiZXhwb3J0c1snZGVzLWVjYiddID0ge1xuICBrZXk6IDgsXG4gIGl2OiAwXG59XG5leHBvcnRzWydkZXMtY2JjJ10gPSBleHBvcnRzLmRlcyA9IHtcbiAga2V5OiA4LFxuICBpdjogOFxufVxuZXhwb3J0c1snZGVzLWVkZTMtY2JjJ10gPSBleHBvcnRzLmRlczMgPSB7XG4gIGtleTogMjQsXG4gIGl2OiA4XG59XG5leHBvcnRzWydkZXMtZWRlMyddID0ge1xuICBrZXk6IDI0LFxuICBpdjogMFxufVxuZXhwb3J0c1snZGVzLWVkZS1jYmMnXSA9IHtcbiAga2V5OiAxNixcbiAgaXY6IDhcbn1cbmV4cG9ydHNbJ2Rlcy1lZGUnXSA9IHtcbiAga2V5OiAxNixcbiAgaXY6IDBcbn1cbiIsInZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdzdHJlYW0nKS5UcmFuc2Zvcm1cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXInKS5TdHJpbmdEZWNvZGVyXG5tb2R1bGUuZXhwb3J0cyA9IENpcGhlckJhc2VcbmluaGVyaXRzKENpcGhlckJhc2UsIFRyYW5zZm9ybSlcbmZ1bmN0aW9uIENpcGhlckJhc2UgKGhhc2hNb2RlKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG4gIHRoaXMuaGFzaE1vZGUgPSB0eXBlb2YgaGFzaE1vZGUgPT09ICdzdHJpbmcnXG4gIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgdGhpc1toYXNoTW9kZV0gPSB0aGlzLl9maW5hbE9yRGlnZXN0XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5maW5hbCA9IHRoaXMuX2ZpbmFsT3JEaWdlc3RcbiAgfVxuICB0aGlzLl9kZWNvZGVyID0gbnVsbFxuICB0aGlzLl9lbmNvZGluZyA9IG51bGxcbn1cbkNpcGhlckJhc2UucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhLCBpbnB1dEVuYywgb3V0cHV0RW5jKSB7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICBkYXRhID0gbmV3IEJ1ZmZlcihkYXRhLCBpbnB1dEVuYylcbiAgfVxuICB2YXIgb3V0RGF0YSA9IHRoaXMuX3VwZGF0ZShkYXRhKVxuICBpZiAodGhpcy5oYXNoTW9kZSkge1xuICAgIHJldHVybiB0aGlzXG4gIH1cbiAgaWYgKG91dHB1dEVuYykge1xuICAgIG91dERhdGEgPSB0aGlzLl90b1N0cmluZyhvdXREYXRhLCBvdXRwdXRFbmMpXG4gIH1cbiAgcmV0dXJuIG91dERhdGFcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuc2V0QXV0b1BhZGRpbmcgPSBmdW5jdGlvbiAoKSB7fVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5nZXRBdXRoVGFnID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3RyeWluZyB0byBnZXQgYXV0aCB0YWcgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBdXRoVGFnID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3RyeWluZyB0byBzZXQgYXV0aCB0YWcgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBQUQgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIHNldCBhYWQgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24gKGRhdGEsIF8sIG5leHQpIHtcbiAgdmFyIGVyclxuICB0cnkge1xuICAgIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgICB0aGlzLl91cGRhdGUoZGF0YSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wdXNoKHRoaXMuX3VwZGF0ZShkYXRhKSlcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBlcnIgPSBlXG4gIH0gZmluYWxseSB7XG4gICAgbmV4dChlcnIpXG4gIH1cbn1cbkNpcGhlckJhc2UucHJvdG90eXBlLl9mbHVzaCA9IGZ1bmN0aW9uIChkb25lKSB7XG4gIHZhciBlcnJcbiAgdHJ5IHtcbiAgICB0aGlzLnB1c2godGhpcy5fZmluYWwoKSlcbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfSBmaW5hbGx5IHtcbiAgICBkb25lKGVycilcbiAgfVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZpbmFsT3JEaWdlc3QgPSBmdW5jdGlvbiAob3V0cHV0RW5jKSB7XG4gIHZhciBvdXREYXRhID0gdGhpcy5fZmluYWwoKSB8fCBuZXcgQnVmZmVyKCcnKVxuICBpZiAob3V0cHV0RW5jKSB7XG4gICAgb3V0RGF0YSA9IHRoaXMuX3RvU3RyaW5nKG91dERhdGEsIG91dHB1dEVuYywgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb3V0RGF0YVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fdG9TdHJpbmcgPSBmdW5jdGlvbiAodmFsdWUsIGVuYywgZmluYWwpIHtcbiAgaWYgKCF0aGlzLl9kZWNvZGVyKSB7XG4gICAgdGhpcy5fZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKGVuYylcbiAgICB0aGlzLl9lbmNvZGluZyA9IGVuY1xuICB9XG4gIGlmICh0aGlzLl9lbmNvZGluZyAhPT0gZW5jKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjYW5cXCd0IHN3aXRjaCBlbmNvZGluZ3MnKVxuICB9XG4gIHZhciBvdXQgPSB0aGlzLl9kZWNvZGVyLndyaXRlKHZhbHVlKVxuICBpZiAoZmluYWwpIHtcbiAgICBvdXQgKz0gdGhpcy5fZGVjb2Rlci5lbmQoKVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy51dGlscyA9IHJlcXVpcmUoJy4vZGVzL3V0aWxzJyk7XG5leHBvcnRzLkNpcGhlciA9IHJlcXVpcmUoJy4vZGVzL2NpcGhlcicpO1xuZXhwb3J0cy5ERVMgPSByZXF1aXJlKCcuL2Rlcy9kZXMnKTtcbmV4cG9ydHMuQ0JDID0gcmVxdWlyZSgnLi9kZXMvY2JjJyk7XG5leHBvcnRzLkVERSA9IHJlcXVpcmUoJy4vZGVzL2VkZScpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxudmFyIHByb3RvID0ge307XG5cbmZ1bmN0aW9uIENCQ1N0YXRlKGl2KSB7XG4gIGFzc2VydC5lcXVhbChpdi5sZW5ndGgsIDgsICdJbnZhbGlkIElWIGxlbmd0aCcpO1xuXG4gIHRoaXMuaXYgPSBuZXcgQXJyYXkoOCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5pdi5sZW5ndGg7IGkrKylcbiAgICB0aGlzLml2W2ldID0gaXZbaV07XG59XG5cbmZ1bmN0aW9uIGluc3RhbnRpYXRlKEJhc2UpIHtcbiAgZnVuY3Rpb24gQ0JDKG9wdGlvbnMpIHtcbiAgICBCYXNlLmNhbGwodGhpcywgb3B0aW9ucyk7XG4gICAgdGhpcy5fY2JjSW5pdCgpO1xuICB9XG4gIGluaGVyaXRzKENCQywgQmFzZSk7XG5cbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm90byk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgIENCQy5wcm90b3R5cGVba2V5XSA9IHByb3RvW2tleV07XG4gIH1cblxuICBDQkMuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKG9wdGlvbnMpIHtcbiAgICByZXR1cm4gbmV3IENCQyhvcHRpb25zKTtcbiAgfTtcblxuICByZXR1cm4gQ0JDO1xufVxuXG5leHBvcnRzLmluc3RhbnRpYXRlID0gaW5zdGFudGlhdGU7XG5cbnByb3RvLl9jYmNJbml0ID0gZnVuY3Rpb24gX2NiY0luaXQoKSB7XG4gIHZhciBzdGF0ZSA9IG5ldyBDQkNTdGF0ZSh0aGlzLm9wdGlvbnMuaXYpO1xuICB0aGlzLl9jYmNTdGF0ZSA9IHN0YXRlO1xufTtcblxucHJvdG8uX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUoaW5wLCBpbk9mZiwgb3V0LCBvdXRPZmYpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fY2JjU3RhdGU7XG4gIHZhciBzdXBlclByb3RvID0gdGhpcy5jb25zdHJ1Y3Rvci5zdXBlcl8ucHJvdG90eXBlO1xuXG4gIHZhciBpdiA9IHN0YXRlLml2O1xuICBpZiAodGhpcy50eXBlID09PSAnZW5jcnlwdCcpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspXG4gICAgICBpdltpXSBePSBpbnBbaW5PZmYgKyBpXTtcblxuICAgIHN1cGVyUHJvdG8uX3VwZGF0ZS5jYWxsKHRoaXMsIGl2LCAwLCBvdXQsIG91dE9mZik7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspXG4gICAgICBpdltpXSA9IG91dFtvdXRPZmYgKyBpXTtcbiAgfSBlbHNlIHtcbiAgICBzdXBlclByb3RvLl91cGRhdGUuY2FsbCh0aGlzLCBpbnAsIGluT2ZmLCBvdXQsIG91dE9mZik7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspXG4gICAgICBvdXRbb3V0T2ZmICsgaV0gXj0gaXZbaV07XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspXG4gICAgICBpdltpXSA9IGlucFtpbk9mZiArIGldO1xuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG5mdW5jdGlvbiBDaXBoZXIob3B0aW9ucykge1xuICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXG4gIHRoaXMudHlwZSA9IHRoaXMub3B0aW9ucy50eXBlO1xuICB0aGlzLmJsb2NrU2l6ZSA9IDg7XG4gIHRoaXMuX2luaXQoKTtcblxuICB0aGlzLmJ1ZmZlciA9IG5ldyBBcnJheSh0aGlzLmJsb2NrU2l6ZSk7XG4gIHRoaXMuYnVmZmVyT2ZmID0gMDtcbn1cbm1vZHVsZS5leHBvcnRzID0gQ2lwaGVyO1xuXG5DaXBoZXIucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24gX2luaXQoKSB7XG4gIC8vIE1pZ2h0IGJlIG92ZXJyaWRlZFxufTtcblxuQ2lwaGVyLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUoZGF0YSkge1xuICBpZiAoZGF0YS5sZW5ndGggPT09IDApXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0aGlzLnR5cGUgPT09ICdkZWNyeXB0JylcbiAgICByZXR1cm4gdGhpcy5fdXBkYXRlRGVjcnlwdChkYXRhKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLl91cGRhdGVFbmNyeXB0KGRhdGEpO1xufTtcblxuQ2lwaGVyLnByb3RvdHlwZS5fYnVmZmVyID0gZnVuY3Rpb24gX2J1ZmZlcihkYXRhLCBvZmYpIHtcbiAgLy8gQXBwZW5kIGRhdGEgdG8gYnVmZmVyXG4gIHZhciBtaW4gPSBNYXRoLm1pbih0aGlzLmJ1ZmZlci5sZW5ndGggLSB0aGlzLmJ1ZmZlck9mZiwgZGF0YS5sZW5ndGggLSBvZmYpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG1pbjsgaSsrKVxuICAgIHRoaXMuYnVmZmVyW3RoaXMuYnVmZmVyT2ZmICsgaV0gPSBkYXRhW29mZiArIGldO1xuICB0aGlzLmJ1ZmZlck9mZiArPSBtaW47XG5cbiAgLy8gU2hpZnQgbmV4dFxuICByZXR1cm4gbWluO1xufTtcblxuQ2lwaGVyLnByb3RvdHlwZS5fZmx1c2hCdWZmZXIgPSBmdW5jdGlvbiBfZmx1c2hCdWZmZXIob3V0LCBvZmYpIHtcbiAgdGhpcy5fdXBkYXRlKHRoaXMuYnVmZmVyLCAwLCBvdXQsIG9mZik7XG4gIHRoaXMuYnVmZmVyT2ZmID0gMDtcbiAgcmV0dXJuIHRoaXMuYmxvY2tTaXplO1xufTtcblxuQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlRW5jcnlwdCA9IGZ1bmN0aW9uIF91cGRhdGVFbmNyeXB0KGRhdGEpIHtcbiAgdmFyIGlucHV0T2ZmID0gMDtcbiAgdmFyIG91dHB1dE9mZiA9IDA7XG5cbiAgdmFyIGNvdW50ID0gKCh0aGlzLmJ1ZmZlck9mZiArIGRhdGEubGVuZ3RoKSAvIHRoaXMuYmxvY2tTaXplKSB8IDA7XG4gIHZhciBvdXQgPSBuZXcgQXJyYXkoY291bnQgKiB0aGlzLmJsb2NrU2l6ZSk7XG5cbiAgaWYgKHRoaXMuYnVmZmVyT2ZmICE9PSAwKSB7XG4gICAgaW5wdXRPZmYgKz0gdGhpcy5fYnVmZmVyKGRhdGEsIGlucHV0T2ZmKTtcblxuICAgIGlmICh0aGlzLmJ1ZmZlck9mZiA9PT0gdGhpcy5idWZmZXIubGVuZ3RoKVxuICAgICAgb3V0cHV0T2ZmICs9IHRoaXMuX2ZsdXNoQnVmZmVyKG91dCwgb3V0cHV0T2ZmKTtcbiAgfVxuXG4gIC8vIFdyaXRlIGJsb2Nrc1xuICB2YXIgbWF4ID0gZGF0YS5sZW5ndGggLSAoKGRhdGEubGVuZ3RoIC0gaW5wdXRPZmYpICUgdGhpcy5ibG9ja1NpemUpO1xuICBmb3IgKDsgaW5wdXRPZmYgPCBtYXg7IGlucHV0T2ZmICs9IHRoaXMuYmxvY2tTaXplKSB7XG4gICAgdGhpcy5fdXBkYXRlKGRhdGEsIGlucHV0T2ZmLCBvdXQsIG91dHB1dE9mZik7XG4gICAgb3V0cHV0T2ZmICs9IHRoaXMuYmxvY2tTaXplO1xuICB9XG5cbiAgLy8gUXVldWUgcmVzdFxuICBmb3IgKDsgaW5wdXRPZmYgPCBkYXRhLmxlbmd0aDsgaW5wdXRPZmYrKywgdGhpcy5idWZmZXJPZmYrKylcbiAgICB0aGlzLmJ1ZmZlclt0aGlzLmJ1ZmZlck9mZl0gPSBkYXRhW2lucHV0T2ZmXTtcblxuICByZXR1cm4gb3V0O1xufTtcblxuQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlRGVjcnlwdCA9IGZ1bmN0aW9uIF91cGRhdGVEZWNyeXB0KGRhdGEpIHtcbiAgdmFyIGlucHV0T2ZmID0gMDtcbiAgdmFyIG91dHB1dE9mZiA9IDA7XG5cbiAgdmFyIGNvdW50ID0gTWF0aC5jZWlsKCh0aGlzLmJ1ZmZlck9mZiArIGRhdGEubGVuZ3RoKSAvIHRoaXMuYmxvY2tTaXplKSAtIDE7XG4gIHZhciBvdXQgPSBuZXcgQXJyYXkoY291bnQgKiB0aGlzLmJsb2NrU2l6ZSk7XG5cbiAgLy8gVE9ETyhpbmR1dG55KTogb3B0aW1pemUgaXQsIHRoaXMgaXMgZmFyIGZyb20gb3B0aW1hbFxuICBmb3IgKDsgY291bnQgPiAwOyBjb3VudC0tKSB7XG4gICAgaW5wdXRPZmYgKz0gdGhpcy5fYnVmZmVyKGRhdGEsIGlucHV0T2ZmKTtcbiAgICBvdXRwdXRPZmYgKz0gdGhpcy5fZmx1c2hCdWZmZXIob3V0LCBvdXRwdXRPZmYpO1xuICB9XG5cbiAgLy8gQnVmZmVyIHJlc3Qgb2YgdGhlIGlucHV0XG4gIGlucHV0T2ZmICs9IHRoaXMuX2J1ZmZlcihkYXRhLCBpbnB1dE9mZik7XG5cbiAgcmV0dXJuIG91dDtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuZmluYWwgPSBmdW5jdGlvbiBmaW5hbChidWZmZXIpIHtcbiAgdmFyIGZpcnN0O1xuICBpZiAoYnVmZmVyKVxuICAgIGZpcnN0ID0gdGhpcy51cGRhdGUoYnVmZmVyKTtcblxuICB2YXIgbGFzdDtcbiAgaWYgKHRoaXMudHlwZSA9PT0gJ2VuY3J5cHQnKVxuICAgIGxhc3QgPSB0aGlzLl9maW5hbEVuY3J5cHQoKTtcbiAgZWxzZVxuICAgIGxhc3QgPSB0aGlzLl9maW5hbERlY3J5cHQoKTtcblxuICBpZiAoZmlyc3QpXG4gICAgcmV0dXJuIGZpcnN0LmNvbmNhdChsYXN0KTtcbiAgZWxzZVxuICAgIHJldHVybiBsYXN0O1xufTtcblxuQ2lwaGVyLnByb3RvdHlwZS5fcGFkID0gZnVuY3Rpb24gX3BhZChidWZmZXIsIG9mZikge1xuICBpZiAob2ZmID09PSAwKVxuICAgIHJldHVybiBmYWxzZTtcblxuICB3aGlsZSAob2ZmIDwgYnVmZmVyLmxlbmd0aClcbiAgICBidWZmZXJbb2ZmKytdID0gMDtcblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuX2ZpbmFsRW5jcnlwdCA9IGZ1bmN0aW9uIF9maW5hbEVuY3J5cHQoKSB7XG4gIGlmICghdGhpcy5fcGFkKHRoaXMuYnVmZmVyLCB0aGlzLmJ1ZmZlck9mZikpXG4gICAgcmV0dXJuIFtdO1xuXG4gIHZhciBvdXQgPSBuZXcgQXJyYXkodGhpcy5ibG9ja1NpemUpO1xuICB0aGlzLl91cGRhdGUodGhpcy5idWZmZXIsIDAsIG91dCwgMCk7XG4gIHJldHVybiBvdXQ7XG59O1xuXG5DaXBoZXIucHJvdG90eXBlLl91bnBhZCA9IGZ1bmN0aW9uIF91bnBhZChidWZmZXIpIHtcbiAgcmV0dXJuIGJ1ZmZlcjtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuX2ZpbmFsRGVjcnlwdCA9IGZ1bmN0aW9uIF9maW5hbERlY3J5cHQoKSB7XG4gIGFzc2VydC5lcXVhbCh0aGlzLmJ1ZmZlck9mZiwgdGhpcy5ibG9ja1NpemUsICdOb3QgZW5vdWdoIGRhdGEgdG8gZGVjcnlwdCcpO1xuICB2YXIgb3V0ID0gbmV3IEFycmF5KHRoaXMuYmxvY2tTaXplKTtcbiAgdGhpcy5fZmx1c2hCdWZmZXIob3V0LCAwKTtcblxuICByZXR1cm4gdGhpcy5fdW5wYWQob3V0KTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdtaW5pbWFsaXN0aWMtYXNzZXJ0Jyk7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG52YXIgZGVzID0gcmVxdWlyZSgnLi4vZGVzJyk7XG52YXIgdXRpbHMgPSBkZXMudXRpbHM7XG52YXIgQ2lwaGVyID0gZGVzLkNpcGhlcjtcblxuZnVuY3Rpb24gREVTU3RhdGUoKSB7XG4gIHRoaXMudG1wID0gbmV3IEFycmF5KDIpO1xuICB0aGlzLmtleXMgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBERVMob3B0aW9ucykge1xuICBDaXBoZXIuY2FsbCh0aGlzLCBvcHRpb25zKTtcblxuICB2YXIgc3RhdGUgPSBuZXcgREVTU3RhdGUoKTtcbiAgdGhpcy5fZGVzU3RhdGUgPSBzdGF0ZTtcblxuICB0aGlzLmRlcml2ZUtleXMoc3RhdGUsIG9wdGlvbnMua2V5KTtcbn1cbmluaGVyaXRzKERFUywgQ2lwaGVyKTtcbm1vZHVsZS5leHBvcnRzID0gREVTO1xuXG5ERVMuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKG9wdGlvbnMpIHtcbiAgcmV0dXJuIG5ldyBERVMob3B0aW9ucyk7XG59O1xuXG52YXIgc2hpZnRUYWJsZSA9IFtcbiAgMSwgMSwgMiwgMiwgMiwgMiwgMiwgMixcbiAgMSwgMiwgMiwgMiwgMiwgMiwgMiwgMVxuXTtcblxuREVTLnByb3RvdHlwZS5kZXJpdmVLZXlzID0gZnVuY3Rpb24gZGVyaXZlS2V5cyhzdGF0ZSwga2V5KSB7XG4gIHN0YXRlLmtleXMgPSBuZXcgQXJyYXkoMTYgKiAyKTtcblxuICBhc3NlcnQuZXF1YWwoa2V5Lmxlbmd0aCwgdGhpcy5ibG9ja1NpemUsICdJbnZhbGlkIGtleSBsZW5ndGgnKTtcblxuICB2YXIga0wgPSB1dGlscy5yZWFkVUludDMyQkUoa2V5LCAwKTtcbiAgdmFyIGtSID0gdXRpbHMucmVhZFVJbnQzMkJFKGtleSwgNCk7XG5cbiAgdXRpbHMucGMxKGtMLCBrUiwgc3RhdGUudG1wLCAwKTtcbiAga0wgPSBzdGF0ZS50bXBbMF07XG4gIGtSID0gc3RhdGUudG1wWzFdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0YXRlLmtleXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICB2YXIgc2hpZnQgPSBzaGlmdFRhYmxlW2kgPj4+IDFdO1xuICAgIGtMID0gdXRpbHMucjI4c2hsKGtMLCBzaGlmdCk7XG4gICAga1IgPSB1dGlscy5yMjhzaGwoa1IsIHNoaWZ0KTtcbiAgICB1dGlscy5wYzIoa0wsIGtSLCBzdGF0ZS5rZXlzLCBpKTtcbiAgfVxufTtcblxuREVTLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gX3VwZGF0ZShpbnAsIGluT2ZmLCBvdXQsIG91dE9mZikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9kZXNTdGF0ZTtcblxuICB2YXIgbCA9IHV0aWxzLnJlYWRVSW50MzJCRShpbnAsIGluT2ZmKTtcbiAgdmFyIHIgPSB1dGlscy5yZWFkVUludDMyQkUoaW5wLCBpbk9mZiArIDQpO1xuXG4gIC8vIEluaXRpYWwgUGVybXV0YXRpb25cbiAgdXRpbHMuaXAobCwgciwgc3RhdGUudG1wLCAwKTtcbiAgbCA9IHN0YXRlLnRtcFswXTtcbiAgciA9IHN0YXRlLnRtcFsxXTtcblxuICBpZiAodGhpcy50eXBlID09PSAnZW5jcnlwdCcpXG4gICAgdGhpcy5fZW5jcnlwdChzdGF0ZSwgbCwgciwgc3RhdGUudG1wLCAwKTtcbiAgZWxzZVxuICAgIHRoaXMuX2RlY3J5cHQoc3RhdGUsIGwsIHIsIHN0YXRlLnRtcCwgMCk7XG5cbiAgbCA9IHN0YXRlLnRtcFswXTtcbiAgciA9IHN0YXRlLnRtcFsxXTtcblxuICB1dGlscy53cml0ZVVJbnQzMkJFKG91dCwgbCwgb3V0T2ZmKTtcbiAgdXRpbHMud3JpdGVVSW50MzJCRShvdXQsIHIsIG91dE9mZiArIDQpO1xufTtcblxuREVTLnByb3RvdHlwZS5fcGFkID0gZnVuY3Rpb24gX3BhZChidWZmZXIsIG9mZikge1xuICB2YXIgdmFsdWUgPSBidWZmZXIubGVuZ3RoIC0gb2ZmO1xuICBmb3IgKHZhciBpID0gb2ZmOyBpIDwgYnVmZmVyLmxlbmd0aDsgaSsrKVxuICAgIGJ1ZmZlcltpXSA9IHZhbHVlO1xuXG4gIHJldHVybiB0cnVlO1xufTtcblxuREVTLnByb3RvdHlwZS5fdW5wYWQgPSBmdW5jdGlvbiBfdW5wYWQoYnVmZmVyKSB7XG4gIHZhciBwYWQgPSBidWZmZXJbYnVmZmVyLmxlbmd0aCAtIDFdO1xuICBmb3IgKHZhciBpID0gYnVmZmVyLmxlbmd0aCAtIHBhZDsgaSA8IGJ1ZmZlci5sZW5ndGg7IGkrKylcbiAgICBhc3NlcnQuZXF1YWwoYnVmZmVyW2ldLCBwYWQpO1xuXG4gIHJldHVybiBidWZmZXIuc2xpY2UoMCwgYnVmZmVyLmxlbmd0aCAtIHBhZCk7XG59O1xuXG5ERVMucHJvdG90eXBlLl9lbmNyeXB0ID0gZnVuY3Rpb24gX2VuY3J5cHQoc3RhdGUsIGxTdGFydCwgclN0YXJ0LCBvdXQsIG9mZikge1xuICB2YXIgbCA9IGxTdGFydDtcbiAgdmFyIHIgPSByU3RhcnQ7XG5cbiAgLy8gQXBwbHkgZigpIHgxNiB0aW1lc1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0YXRlLmtleXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICB2YXIga2V5TCA9IHN0YXRlLmtleXNbaV07XG4gICAgdmFyIGtleVIgPSBzdGF0ZS5rZXlzW2kgKyAxXTtcblxuICAgIC8vIGYociwgaylcbiAgICB1dGlscy5leHBhbmQociwgc3RhdGUudG1wLCAwKTtcblxuICAgIGtleUwgXj0gc3RhdGUudG1wWzBdO1xuICAgIGtleVIgXj0gc3RhdGUudG1wWzFdO1xuICAgIHZhciBzID0gdXRpbHMuc3Vic3RpdHV0ZShrZXlMLCBrZXlSKTtcbiAgICB2YXIgZiA9IHV0aWxzLnBlcm11dGUocyk7XG5cbiAgICB2YXIgdCA9IHI7XG4gICAgciA9IChsIF4gZikgPj4+IDA7XG4gICAgbCA9IHQ7XG4gIH1cblxuICAvLyBSZXZlcnNlIEluaXRpYWwgUGVybXV0YXRpb25cbiAgdXRpbHMucmlwKHIsIGwsIG91dCwgb2ZmKTtcbn07XG5cbkRFUy5wcm90b3R5cGUuX2RlY3J5cHQgPSBmdW5jdGlvbiBfZGVjcnlwdChzdGF0ZSwgbFN0YXJ0LCByU3RhcnQsIG91dCwgb2ZmKSB7XG4gIHZhciBsID0gclN0YXJ0O1xuICB2YXIgciA9IGxTdGFydDtcblxuICAvLyBBcHBseSBmKCkgeDE2IHRpbWVzXG4gIGZvciAodmFyIGkgPSBzdGF0ZS5rZXlzLmxlbmd0aCAtIDI7IGkgPj0gMDsgaSAtPSAyKSB7XG4gICAgdmFyIGtleUwgPSBzdGF0ZS5rZXlzW2ldO1xuICAgIHZhciBrZXlSID0gc3RhdGUua2V5c1tpICsgMV07XG5cbiAgICAvLyBmKHIsIGspXG4gICAgdXRpbHMuZXhwYW5kKGwsIHN0YXRlLnRtcCwgMCk7XG5cbiAgICBrZXlMIF49IHN0YXRlLnRtcFswXTtcbiAgICBrZXlSIF49IHN0YXRlLnRtcFsxXTtcbiAgICB2YXIgcyA9IHV0aWxzLnN1YnN0aXR1dGUoa2V5TCwga2V5Uik7XG4gICAgdmFyIGYgPSB1dGlscy5wZXJtdXRlKHMpO1xuXG4gICAgdmFyIHQgPSBsO1xuICAgIGwgPSAociBeIGYpID4+PiAwO1xuICAgIHIgPSB0O1xuICB9XG5cbiAgLy8gUmV2ZXJzZSBJbml0aWFsIFBlcm11dGF0aW9uXG4gIHV0aWxzLnJpcChsLCByLCBvdXQsIG9mZik7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxudmFyIGRlcyA9IHJlcXVpcmUoJy4uL2RlcycpO1xudmFyIENpcGhlciA9IGRlcy5DaXBoZXI7XG52YXIgREVTID0gZGVzLkRFUztcblxuZnVuY3Rpb24gRURFU3RhdGUodHlwZSwga2V5KSB7XG4gIGFzc2VydC5lcXVhbChrZXkubGVuZ3RoLCAyNCwgJ0ludmFsaWQga2V5IGxlbmd0aCcpO1xuXG4gIHZhciBrMSA9IGtleS5zbGljZSgwLCA4KTtcbiAgdmFyIGsyID0ga2V5LnNsaWNlKDgsIDE2KTtcbiAgdmFyIGszID0ga2V5LnNsaWNlKDE2LCAyNCk7XG5cbiAgaWYgKHR5cGUgPT09ICdlbmNyeXB0Jykge1xuICAgIHRoaXMuY2lwaGVycyA9IFtcbiAgICAgIERFUy5jcmVhdGUoeyB0eXBlOiAnZW5jcnlwdCcsIGtleTogazEgfSksXG4gICAgICBERVMuY3JlYXRlKHsgdHlwZTogJ2RlY3J5cHQnLCBrZXk6IGsyIH0pLFxuICAgICAgREVTLmNyZWF0ZSh7IHR5cGU6ICdlbmNyeXB0Jywga2V5OiBrMyB9KVxuICAgIF07XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5jaXBoZXJzID0gW1xuICAgICAgREVTLmNyZWF0ZSh7IHR5cGU6ICdkZWNyeXB0Jywga2V5OiBrMyB9KSxcbiAgICAgIERFUy5jcmVhdGUoeyB0eXBlOiAnZW5jcnlwdCcsIGtleTogazIgfSksXG4gICAgICBERVMuY3JlYXRlKHsgdHlwZTogJ2RlY3J5cHQnLCBrZXk6IGsxIH0pXG4gICAgXTtcbiAgfVxufVxuXG5mdW5jdGlvbiBFREUob3B0aW9ucykge1xuICBDaXBoZXIuY2FsbCh0aGlzLCBvcHRpb25zKTtcblxuICB2YXIgc3RhdGUgPSBuZXcgRURFU3RhdGUodGhpcy50eXBlLCB0aGlzLm9wdGlvbnMua2V5KTtcbiAgdGhpcy5fZWRlU3RhdGUgPSBzdGF0ZTtcbn1cbmluaGVyaXRzKEVERSwgQ2lwaGVyKTtcblxubW9kdWxlLmV4cG9ydHMgPSBFREU7XG5cbkVERS5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUob3B0aW9ucykge1xuICByZXR1cm4gbmV3IEVERShvcHRpb25zKTtcbn07XG5cbkVERS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUoaW5wLCBpbk9mZiwgb3V0LCBvdXRPZmYpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fZWRlU3RhdGU7XG5cbiAgc3RhdGUuY2lwaGVyc1swXS5fdXBkYXRlKGlucCwgaW5PZmYsIG91dCwgb3V0T2ZmKTtcbiAgc3RhdGUuY2lwaGVyc1sxXS5fdXBkYXRlKG91dCwgb3V0T2ZmLCBvdXQsIG91dE9mZik7XG4gIHN0YXRlLmNpcGhlcnNbMl0uX3VwZGF0ZShvdXQsIG91dE9mZiwgb3V0LCBvdXRPZmYpO1xufTtcblxuRURFLnByb3RvdHlwZS5fcGFkID0gREVTLnByb3RvdHlwZS5fcGFkO1xuRURFLnByb3RvdHlwZS5fdW5wYWQgPSBERVMucHJvdG90eXBlLl91bnBhZDtcbiIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiByZWFkVUludDMyQkUoYnl0ZXMsIG9mZikge1xuICB2YXIgcmVzID0gIChieXRlc1swICsgb2ZmXSA8PCAyNCkgfFxuICAgICAgICAgICAgIChieXRlc1sxICsgb2ZmXSA8PCAxNikgfFxuICAgICAgICAgICAgIChieXRlc1syICsgb2ZmXSA8PCA4KSB8XG4gICAgICAgICAgICAgYnl0ZXNbMyArIG9mZl07XG4gIHJldHVybiByZXMgPj4+IDA7XG59O1xuXG5leHBvcnRzLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFKGJ5dGVzLCB2YWx1ZSwgb2ZmKSB7XG4gIGJ5dGVzWzAgKyBvZmZdID0gdmFsdWUgPj4+IDI0O1xuICBieXRlc1sxICsgb2ZmXSA9ICh2YWx1ZSA+Pj4gMTYpICYgMHhmZjtcbiAgYnl0ZXNbMiArIG9mZl0gPSAodmFsdWUgPj4+IDgpICYgMHhmZjtcbiAgYnl0ZXNbMyArIG9mZl0gPSB2YWx1ZSAmIDB4ZmY7XG59O1xuXG5leHBvcnRzLmlwID0gZnVuY3Rpb24gaXAoaW5MLCBpblIsIG91dCwgb2ZmKSB7XG4gIHZhciBvdXRMID0gMDtcbiAgdmFyIG91dFIgPSAwO1xuXG4gIGZvciAodmFyIGkgPSA2OyBpID49IDA7IGkgLT0gMikge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDw9IDI0OyBqICs9IDgpIHtcbiAgICAgIG91dEwgPDw9IDE7XG4gICAgICBvdXRMIHw9IChpblIgPj4+IChqICsgaSkpICYgMTtcbiAgICB9XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPD0gMjQ7IGogKz0gOCkge1xuICAgICAgb3V0TCA8PD0gMTtcbiAgICAgIG91dEwgfD0gKGluTCA+Pj4gKGogKyBpKSkgJiAxO1xuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIGkgPSA2OyBpID49IDA7IGkgLT0gMikge1xuICAgIGZvciAodmFyIGogPSAxOyBqIDw9IDI1OyBqICs9IDgpIHtcbiAgICAgIG91dFIgPDw9IDE7XG4gICAgICBvdXRSIHw9IChpblIgPj4+IChqICsgaSkpICYgMTtcbiAgICB9XG4gICAgZm9yICh2YXIgaiA9IDE7IGogPD0gMjU7IGogKz0gOCkge1xuICAgICAgb3V0UiA8PD0gMTtcbiAgICAgIG91dFIgfD0gKGluTCA+Pj4gKGogKyBpKSkgJiAxO1xuICAgIH1cbiAgfVxuXG4gIG91dFtvZmYgKyAwXSA9IG91dEwgPj4+IDA7XG4gIG91dFtvZmYgKyAxXSA9IG91dFIgPj4+IDA7XG59O1xuXG5leHBvcnRzLnJpcCA9IGZ1bmN0aW9uIHJpcChpbkwsIGluUiwgb3V0LCBvZmYpIHtcbiAgdmFyIG91dEwgPSAwO1xuICB2YXIgb3V0UiA9IDA7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICBmb3IgKHZhciBqID0gMjQ7IGogPj0gMDsgaiAtPSA4KSB7XG4gICAgICBvdXRMIDw8PSAxO1xuICAgICAgb3V0TCB8PSAoaW5SID4+PiAoaiArIGkpKSAmIDE7XG4gICAgICBvdXRMIDw8PSAxO1xuICAgICAgb3V0TCB8PSAoaW5MID4+PiAoaiArIGkpKSAmIDE7XG4gICAgfVxuICB9XG4gIGZvciAodmFyIGkgPSA0OyBpIDwgODsgaSsrKSB7XG4gICAgZm9yICh2YXIgaiA9IDI0OyBqID49IDA7IGogLT0gOCkge1xuICAgICAgb3V0UiA8PD0gMTtcbiAgICAgIG91dFIgfD0gKGluUiA+Pj4gKGogKyBpKSkgJiAxO1xuICAgICAgb3V0UiA8PD0gMTtcbiAgICAgIG91dFIgfD0gKGluTCA+Pj4gKGogKyBpKSkgJiAxO1xuICAgIH1cbiAgfVxuXG4gIG91dFtvZmYgKyAwXSA9IG91dEwgPj4+IDA7XG4gIG91dFtvZmYgKyAxXSA9IG91dFIgPj4+IDA7XG59O1xuXG5leHBvcnRzLnBjMSA9IGZ1bmN0aW9uIHBjMShpbkwsIGluUiwgb3V0LCBvZmYpIHtcbiAgdmFyIG91dEwgPSAwO1xuICB2YXIgb3V0UiA9IDA7XG5cbiAgLy8gNywgMTUsIDIzLCAzMSwgMzksIDQ3LCA1NSwgNjNcbiAgLy8gNiwgMTQsIDIyLCAzMCwgMzksIDQ3LCA1NSwgNjNcbiAgLy8gNSwgMTMsIDIxLCAyOSwgMzksIDQ3LCA1NSwgNjNcbiAgLy8gNCwgMTIsIDIwLCAyOFxuICBmb3IgKHZhciBpID0gNzsgaSA+PSA1OyBpLS0pIHtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8PSAyNDsgaiArPSA4KSB7XG4gICAgICBvdXRMIDw8PSAxO1xuICAgICAgb3V0TCB8PSAoaW5SID4+IChqICsgaSkpICYgMTtcbiAgICB9XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPD0gMjQ7IGogKz0gOCkge1xuICAgICAgb3V0TCA8PD0gMTtcbiAgICAgIG91dEwgfD0gKGluTCA+PiAoaiArIGkpKSAmIDE7XG4gICAgfVxuICB9XG4gIGZvciAodmFyIGogPSAwOyBqIDw9IDI0OyBqICs9IDgpIHtcbiAgICBvdXRMIDw8PSAxO1xuICAgIG91dEwgfD0gKGluUiA+PiAoaiArIGkpKSAmIDE7XG4gIH1cblxuICAvLyAxLCA5LCAxNywgMjUsIDMzLCA0MSwgNDksIDU3XG4gIC8vIDIsIDEwLCAxOCwgMjYsIDM0LCA0MiwgNTAsIDU4XG4gIC8vIDMsIDExLCAxOSwgMjcsIDM1LCA0MywgNTEsIDU5XG4gIC8vIDM2LCA0NCwgNTIsIDYwXG4gIGZvciAodmFyIGkgPSAxOyBpIDw9IDM7IGkrKykge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDw9IDI0OyBqICs9IDgpIHtcbiAgICAgIG91dFIgPDw9IDE7XG4gICAgICBvdXRSIHw9IChpblIgPj4gKGogKyBpKSkgJiAxO1xuICAgIH1cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8PSAyNDsgaiArPSA4KSB7XG4gICAgICBvdXRSIDw8PSAxO1xuICAgICAgb3V0UiB8PSAoaW5MID4+IChqICsgaSkpICYgMTtcbiAgICB9XG4gIH1cbiAgZm9yICh2YXIgaiA9IDA7IGogPD0gMjQ7IGogKz0gOCkge1xuICAgIG91dFIgPDw9IDE7XG4gICAgb3V0UiB8PSAoaW5MID4+IChqICsgaSkpICYgMTtcbiAgfVxuXG4gIG91dFtvZmYgKyAwXSA9IG91dEwgPj4+IDA7XG4gIG91dFtvZmYgKyAxXSA9IG91dFIgPj4+IDA7XG59O1xuXG5leHBvcnRzLnIyOHNobCA9IGZ1bmN0aW9uIHIyOHNobChudW0sIHNoaWZ0KSB7XG4gIHJldHVybiAoKG51bSA8PCBzaGlmdCkgJiAweGZmZmZmZmYpIHwgKG51bSA+Pj4gKDI4IC0gc2hpZnQpKTtcbn07XG5cbnZhciBwYzJ0YWJsZSA9IFtcbiAgLy8gaW5MID0+IG91dExcbiAgMTQsIDExLCAxNywgNCwgMjcsIDIzLCAyNSwgMCxcbiAgMTMsIDIyLCA3LCAxOCwgNSwgOSwgMTYsIDI0LFxuICAyLCAyMCwgMTIsIDIxLCAxLCA4LCAxNSwgMjYsXG5cbiAgLy8gaW5SID0+IG91dFJcbiAgMTUsIDQsIDI1LCAxOSwgOSwgMSwgMjYsIDE2LFxuICA1LCAxMSwgMjMsIDgsIDEyLCA3LCAxNywgMCxcbiAgMjIsIDMsIDEwLCAxNCwgNiwgMjAsIDI3LCAyNFxuXTtcblxuZXhwb3J0cy5wYzIgPSBmdW5jdGlvbiBwYzIoaW5MLCBpblIsIG91dCwgb2ZmKSB7XG4gIHZhciBvdXRMID0gMDtcbiAgdmFyIG91dFIgPSAwO1xuXG4gIHZhciBsZW4gPSBwYzJ0YWJsZS5sZW5ndGggPj4+IDE7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICBvdXRMIDw8PSAxO1xuICAgIG91dEwgfD0gKGluTCA+Pj4gcGMydGFibGVbaV0pICYgMHgxO1xuICB9XG4gIGZvciAodmFyIGkgPSBsZW47IGkgPCBwYzJ0YWJsZS5sZW5ndGg7IGkrKykge1xuICAgIG91dFIgPDw9IDE7XG4gICAgb3V0UiB8PSAoaW5SID4+PiBwYzJ0YWJsZVtpXSkgJiAweDE7XG4gIH1cblxuICBvdXRbb2ZmICsgMF0gPSBvdXRMID4+PiAwO1xuICBvdXRbb2ZmICsgMV0gPSBvdXRSID4+PiAwO1xufTtcblxuZXhwb3J0cy5leHBhbmQgPSBmdW5jdGlvbiBleHBhbmQociwgb3V0LCBvZmYpIHtcbiAgdmFyIG91dEwgPSAwO1xuICB2YXIgb3V0UiA9IDA7XG5cbiAgb3V0TCA9ICgociAmIDEpIDw8IDUpIHwgKHIgPj4+IDI3KTtcbiAgZm9yICh2YXIgaSA9IDIzOyBpID49IDE1OyBpIC09IDQpIHtcbiAgICBvdXRMIDw8PSA2O1xuICAgIG91dEwgfD0gKHIgPj4+IGkpICYgMHgzZjtcbiAgfVxuICBmb3IgKHZhciBpID0gMTE7IGkgPj0gMzsgaSAtPSA0KSB7XG4gICAgb3V0UiB8PSAociA+Pj4gaSkgJiAweDNmO1xuICAgIG91dFIgPDw9IDY7XG4gIH1cbiAgb3V0UiB8PSAoKHIgJiAweDFmKSA8PCAxKSB8IChyID4+PiAzMSk7XG5cbiAgb3V0W29mZiArIDBdID0gb3V0TCA+Pj4gMDtcbiAgb3V0W29mZiArIDFdID0gb3V0UiA+Pj4gMDtcbn07XG5cbnZhciBzVGFibGUgPSBbXG4gIDE0LCAwLCA0LCAxNSwgMTMsIDcsIDEsIDQsIDIsIDE0LCAxNSwgMiwgMTEsIDEzLCA4LCAxLFxuICAzLCAxMCwgMTAsIDYsIDYsIDEyLCAxMiwgMTEsIDUsIDksIDksIDUsIDAsIDMsIDcsIDgsXG4gIDQsIDE1LCAxLCAxMiwgMTQsIDgsIDgsIDIsIDEzLCA0LCA2LCA5LCAyLCAxLCAxMSwgNyxcbiAgMTUsIDUsIDEyLCAxMSwgOSwgMywgNywgMTQsIDMsIDEwLCAxMCwgMCwgNSwgNiwgMCwgMTMsXG5cbiAgMTUsIDMsIDEsIDEzLCA4LCA0LCAxNCwgNywgNiwgMTUsIDExLCAyLCAzLCA4LCA0LCAxNCxcbiAgOSwgMTIsIDcsIDAsIDIsIDEsIDEzLCAxMCwgMTIsIDYsIDAsIDksIDUsIDExLCAxMCwgNSxcbiAgMCwgMTMsIDE0LCA4LCA3LCAxMCwgMTEsIDEsIDEwLCAzLCA0LCAxNSwgMTMsIDQsIDEsIDIsXG4gIDUsIDExLCA4LCA2LCAxMiwgNywgNiwgMTIsIDksIDAsIDMsIDUsIDIsIDE0LCAxNSwgOSxcblxuICAxMCwgMTMsIDAsIDcsIDksIDAsIDE0LCA5LCA2LCAzLCAzLCA0LCAxNSwgNiwgNSwgMTAsXG4gIDEsIDIsIDEzLCA4LCAxMiwgNSwgNywgMTQsIDExLCAxMiwgNCwgMTEsIDIsIDE1LCA4LCAxLFxuICAxMywgMSwgNiwgMTAsIDQsIDEzLCA5LCAwLCA4LCA2LCAxNSwgOSwgMywgOCwgMCwgNyxcbiAgMTEsIDQsIDEsIDE1LCAyLCAxNCwgMTIsIDMsIDUsIDExLCAxMCwgNSwgMTQsIDIsIDcsIDEyLFxuXG4gIDcsIDEzLCAxMywgOCwgMTQsIDExLCAzLCA1LCAwLCA2LCA2LCAxNSwgOSwgMCwgMTAsIDMsXG4gIDEsIDQsIDIsIDcsIDgsIDIsIDUsIDEyLCAxMSwgMSwgMTIsIDEwLCA0LCAxNCwgMTUsIDksXG4gIDEwLCAzLCA2LCAxNSwgOSwgMCwgMCwgNiwgMTIsIDEwLCAxMSwgMSwgNywgMTMsIDEzLCA4LFxuICAxNSwgOSwgMSwgNCwgMywgNSwgMTQsIDExLCA1LCAxMiwgMiwgNywgOCwgMiwgNCwgMTQsXG5cbiAgMiwgMTQsIDEyLCAxMSwgNCwgMiwgMSwgMTIsIDcsIDQsIDEwLCA3LCAxMSwgMTMsIDYsIDEsXG4gIDgsIDUsIDUsIDAsIDMsIDE1LCAxNSwgMTAsIDEzLCAzLCAwLCA5LCAxNCwgOCwgOSwgNixcbiAgNCwgMTEsIDIsIDgsIDEsIDEyLCAxMSwgNywgMTAsIDEsIDEzLCAxNCwgNywgMiwgOCwgMTMsXG4gIDE1LCA2LCA5LCAxNSwgMTIsIDAsIDUsIDksIDYsIDEwLCAzLCA0LCAwLCA1LCAxNCwgMyxcblxuICAxMiwgMTAsIDEsIDE1LCAxMCwgNCwgMTUsIDIsIDksIDcsIDIsIDEyLCA2LCA5LCA4LCA1LFxuICAwLCA2LCAxMywgMSwgMywgMTMsIDQsIDE0LCAxNCwgMCwgNywgMTEsIDUsIDMsIDExLCA4LFxuICA5LCA0LCAxNCwgMywgMTUsIDIsIDUsIDEyLCAyLCA5LCA4LCA1LCAxMiwgMTUsIDMsIDEwLFxuICA3LCAxMSwgMCwgMTQsIDQsIDEsIDEwLCA3LCAxLCA2LCAxMywgMCwgMTEsIDgsIDYsIDEzLFxuXG4gIDQsIDEzLCAxMSwgMCwgMiwgMTEsIDE0LCA3LCAxNSwgNCwgMCwgOSwgOCwgMSwgMTMsIDEwLFxuICAzLCAxNCwgMTIsIDMsIDksIDUsIDcsIDEyLCA1LCAyLCAxMCwgMTUsIDYsIDgsIDEsIDYsXG4gIDEsIDYsIDQsIDExLCAxMSwgMTMsIDEzLCA4LCAxMiwgMSwgMywgNCwgNywgMTAsIDE0LCA3LFxuICAxMCwgOSwgMTUsIDUsIDYsIDAsIDgsIDE1LCAwLCAxNCwgNSwgMiwgOSwgMywgMiwgMTIsXG5cbiAgMTMsIDEsIDIsIDE1LCA4LCAxMywgNCwgOCwgNiwgMTAsIDE1LCAzLCAxMSwgNywgMSwgNCxcbiAgMTAsIDEyLCA5LCA1LCAzLCA2LCAxNCwgMTEsIDUsIDAsIDAsIDE0LCAxMiwgOSwgNywgMixcbiAgNywgMiwgMTEsIDEsIDQsIDE0LCAxLCA3LCA5LCA0LCAxMiwgMTAsIDE0LCA4LCAyLCAxMyxcbiAgMCwgMTUsIDYsIDEyLCAxMCwgOSwgMTMsIDAsIDE1LCAzLCAzLCA1LCA1LCA2LCA4LCAxMVxuXTtcblxuZXhwb3J0cy5zdWJzdGl0dXRlID0gZnVuY3Rpb24gc3Vic3RpdHV0ZShpbkwsIGluUikge1xuICB2YXIgb3V0ID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICB2YXIgYiA9IChpbkwgPj4+ICgxOCAtIGkgKiA2KSkgJiAweDNmO1xuICAgIHZhciBzYiA9IHNUYWJsZVtpICogMHg0MCArIGJdO1xuXG4gICAgb3V0IDw8PSA0O1xuICAgIG91dCB8PSBzYjtcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIHZhciBiID0gKGluUiA+Pj4gKDE4IC0gaSAqIDYpKSAmIDB4M2Y7XG4gICAgdmFyIHNiID0gc1RhYmxlWzQgKiAweDQwICsgaSAqIDB4NDAgKyBiXTtcblxuICAgIG91dCA8PD0gNDtcbiAgICBvdXQgfD0gc2I7XG4gIH1cbiAgcmV0dXJuIG91dCA+Pj4gMDtcbn07XG5cbnZhciBwZXJtdXRlVGFibGUgPSBbXG4gIDE2LCAyNSwgMTIsIDExLCAzLCAyMCwgNCwgMTUsIDMxLCAxNywgOSwgNiwgMjcsIDE0LCAxLCAyMixcbiAgMzAsIDI0LCA4LCAxOCwgMCwgNSwgMjksIDIzLCAxMywgMTksIDIsIDI2LCAxMCwgMjEsIDI4LCA3XG5dO1xuXG5leHBvcnRzLnBlcm11dGUgPSBmdW5jdGlvbiBwZXJtdXRlKG51bSkge1xuICB2YXIgb3V0ID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwZXJtdXRlVGFibGUubGVuZ3RoOyBpKyspIHtcbiAgICBvdXQgPDw9IDE7XG4gICAgb3V0IHw9IChudW0gPj4+IHBlcm11dGVUYWJsZVtpXSkgJiAweDE7XG4gIH1cbiAgcmV0dXJuIG91dCA+Pj4gMDtcbn07XG5cbmV4cG9ydHMucGFkU3BsaXQgPSBmdW5jdGlvbiBwYWRTcGxpdChudW0sIHNpemUsIGdyb3VwKSB7XG4gIHZhciBzdHIgPSBudW0udG9TdHJpbmcoMik7XG4gIHdoaWxlIChzdHIubGVuZ3RoIDwgc2l6ZSlcbiAgICBzdHIgPSAnMCcgKyBzdHI7XG5cbiAgdmFyIG91dCA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHNpemU7IGkgKz0gZ3JvdXApXG4gICAgb3V0LnB1c2goc3RyLnNsaWNlKGksIGkgKyBncm91cCkpO1xuICByZXR1cm4gb3V0LmpvaW4oJyAnKTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGFzc2VydDtcblxuZnVuY3Rpb24gYXNzZXJ0KHZhbCwgbXNnKSB7XG4gIGlmICghdmFsKVxuICAgIHRocm93IG5ldyBFcnJvcihtc2cgfHwgJ0Fzc2VydGlvbiBmYWlsZWQnKTtcbn1cblxuYXNzZXJ0LmVxdWFsID0gZnVuY3Rpb24gYXNzZXJ0RXF1YWwobCwgciwgbXNnKSB7XG4gIGlmIChsICE9IHIpXG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZyB8fCAoJ0Fzc2VydGlvbiBmYWlsZWQ6ICcgKyBsICsgJyAhPSAnICsgcikpO1xufTtcbiIsInZhciBtZDUgPSByZXF1aXJlKCdjcmVhdGUtaGFzaC9tZDUnKVxubW9kdWxlLmV4cG9ydHMgPSBFVlBfQnl0ZXNUb0tleVxuZnVuY3Rpb24gRVZQX0J5dGVzVG9LZXkgKHBhc3N3b3JkLCBzYWx0LCBrZXlMZW4sIGl2TGVuKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHBhc3N3b3JkKSkge1xuICAgIHBhc3N3b3JkID0gbmV3IEJ1ZmZlcihwYXNzd29yZCwgJ2JpbmFyeScpXG4gIH1cbiAgaWYgKHNhbHQgJiYgIUJ1ZmZlci5pc0J1ZmZlcihzYWx0KSkge1xuICAgIHNhbHQgPSBuZXcgQnVmZmVyKHNhbHQsICdiaW5hcnknKVxuICB9XG4gIGtleUxlbiA9IGtleUxlbiAvIDhcbiAgaXZMZW4gPSBpdkxlbiB8fCAwXG4gIHZhciBraSA9IDBcbiAgdmFyIGlpID0gMFxuICB2YXIga2V5ID0gbmV3IEJ1ZmZlcihrZXlMZW4pXG4gIHZhciBpdiA9IG5ldyBCdWZmZXIoaXZMZW4pXG4gIHZhciBhZGRtZCA9IDBcbiAgdmFyIG1kX2J1ZlxuICB2YXIgaVxuICB2YXIgYnVmcyA9IFtdXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgaWYgKGFkZG1kKysgPiAwKSB7XG4gICAgICBidWZzLnB1c2gobWRfYnVmKVxuICAgIH1cbiAgICBidWZzLnB1c2gocGFzc3dvcmQpXG4gICAgaWYgKHNhbHQpIHtcbiAgICAgIGJ1ZnMucHVzaChzYWx0KVxuICAgIH1cbiAgICBtZF9idWYgPSBtZDUoQnVmZmVyLmNvbmNhdChidWZzKSlcbiAgICBidWZzID0gW11cbiAgICBpID0gMFxuICAgIGlmIChrZXlMZW4gPiAwKSB7XG4gICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBpZiAoa2V5TGVuID09PSAwKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaSA9PT0gbWRfYnVmLmxlbmd0aCkge1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAga2V5W2tpKytdID0gbWRfYnVmW2ldXG4gICAgICAgIGtleUxlbi0tXG4gICAgICAgIGkrK1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXZMZW4gPiAwICYmIGkgIT09IG1kX2J1Zi5sZW5ndGgpIHtcbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGlmIChpdkxlbiA9PT0gMCkge1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGkgPT09IG1kX2J1Zi5sZW5ndGgpIHtcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICAgIGl2W2lpKytdID0gbWRfYnVmW2ldXG4gICAgICAgIGl2TGVuLS1cbiAgICAgICAgaSsrXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChrZXlMZW4gPT09IDAgJiYgaXZMZW4gPT09IDApIHtcbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG4gIGZvciAoaSA9IDA7IGkgPCBtZF9idWYubGVuZ3RoOyBpKyspIHtcbiAgICBtZF9idWZbaV0gPSAwXG4gIH1cbiAgcmV0dXJuIHtcbiAgICBrZXk6IGtleSxcbiAgICBpdjogaXZcbiAgfVxufVxuIiwiJ3VzZSBzdHJpY3QnXG5leHBvcnRzWydSU0EtU0hBMjI0J10gPSBleHBvcnRzLnNoYTIyNFdpdGhSU0FFbmNyeXB0aW9uID0ge1xuICBzaWduOiAncnNhJyxcbiAgaGFzaDogJ3NoYTIyNCcsXG4gIGlkOiBuZXcgQnVmZmVyKCczMDJkMzAwZDA2MDk2MDg2NDgwMTY1MDMwNDAyMDQwNTAwMDQxYycsICdoZXgnKVxufVxuZXhwb3J0c1snUlNBLVNIQTI1NiddID0gZXhwb3J0cy5zaGEyNTZXaXRoUlNBRW5jcnlwdGlvbiA9IHtcbiAgc2lnbjogJ3JzYScsXG4gIGhhc2g6ICdzaGEyNTYnLFxuICBpZDogbmV3IEJ1ZmZlcignMzAzMTMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjAxMDUwMDA0MjAnLCAnaGV4Jylcbn1cbmV4cG9ydHNbJ1JTQS1TSEEzODQnXSA9IGV4cG9ydHMuc2hhMzg0V2l0aFJTQUVuY3J5cHRpb24gPSB7XG4gIHNpZ246ICdyc2EnLFxuICBoYXNoOiAnc2hhMzg0JyxcbiAgaWQ6IG5ldyBCdWZmZXIoJzMwNDEzMDBkMDYwOTYwODY0ODAxNjUwMzA0MDIwMjA1MDAwNDMwJywgJ2hleCcpXG59XG5leHBvcnRzWydSU0EtU0hBNTEyJ10gPSBleHBvcnRzLnNoYTUxMldpdGhSU0FFbmNyeXB0aW9uID0ge1xuICBzaWduOiAncnNhJyxcbiAgaGFzaDogJ3NoYTUxMicsXG4gIGlkOiBuZXcgQnVmZmVyKCczMDUxMzAwZDA2MDk2MDg2NDgwMTY1MDMwNDAyMDMwNTAwMDQ0MCcsICdoZXgnKVxufVxuZXhwb3J0c1snUlNBLVNIQTEnXSA9IHtcbiAgc2lnbjogJ3JzYScsXG4gIGhhc2g6ICdzaGExJyxcbiAgaWQ6IG5ldyBCdWZmZXIoJzMwMjEzMDA5MDYwNTJiMGUwMzAyMWEwNTAwMDQxNCcsICdoZXgnKVxufVxuZXhwb3J0c1snZWNkc2Etd2l0aC1TSEExJ10gPSB7XG4gIHNpZ246ICdlY2RzYScsXG4gIGhhc2g6ICdzaGExJyxcbiAgaWQ6IG5ldyBCdWZmZXIoJycsICdoZXgnKVxufVxuXG5leHBvcnRzLkRTQSA9IGV4cG9ydHNbJ0RTQS1TSEExJ10gPSBleHBvcnRzWydEU0EtU0hBJ10gPSB7XG4gIHNpZ246ICdkc2EnLFxuICBoYXNoOiAnc2hhMScsXG4gIGlkOiBuZXcgQnVmZmVyKCcnLCAnaGV4Jylcbn1cbmV4cG9ydHNbJ0RTQS1TSEEyMjQnXSA9IGV4cG9ydHNbJ0RTQS1XSVRILVNIQTIyNCddID0ge1xuICBzaWduOiAnZHNhJyxcbiAgaGFzaDogJ3NoYTIyNCcsXG4gIGlkOiBuZXcgQnVmZmVyKCcnLCAnaGV4Jylcbn1cbmV4cG9ydHNbJ0RTQS1TSEEyNTYnXSA9IGV4cG9ydHNbJ0RTQS1XSVRILVNIQTI1NiddID0ge1xuICBzaWduOiAnZHNhJyxcbiAgaGFzaDogJ3NoYTI1NicsXG4gIGlkOiBuZXcgQnVmZmVyKCcnLCAnaGV4Jylcbn1cbmV4cG9ydHNbJ0RTQS1TSEEzODQnXSA9IGV4cG9ydHNbJ0RTQS1XSVRILVNIQTM4NCddID0ge1xuICBzaWduOiAnZHNhJyxcbiAgaGFzaDogJ3NoYTM4NCcsXG4gIGlkOiBuZXcgQnVmZmVyKCcnLCAnaGV4Jylcbn1cbmV4cG9ydHNbJ0RTQS1TSEE1MTInXSA9IGV4cG9ydHNbJ0RTQS1XSVRILVNIQTUxMiddID0ge1xuICBzaWduOiAnZHNhJyxcbiAgaGFzaDogJ3NoYTUxMicsXG4gIGlkOiBuZXcgQnVmZmVyKCcnLCAnaGV4Jylcbn1cbmV4cG9ydHNbJ0RTQS1SSVBFTUQxNjAnXSA9IHtcbiAgc2lnbjogJ2RzYScsXG4gIGhhc2g6ICdybWQxNjAnLFxuICBpZDogbmV3IEJ1ZmZlcignJywgJ2hleCcpXG59XG5leHBvcnRzWydSU0EtUklQRU1EMTYwJ10gPSBleHBvcnRzLnJpcGVtZDE2MFdpdGhSU0EgPSB7XG4gIHNpZ246ICdyc2EnLFxuICBoYXNoOiAncm1kMTYwJyxcbiAgaWQ6IG5ldyBCdWZmZXIoJzMwMjEzMDA5MDYwNTJiMjQwMzAyMDEwNTAwMDQxNCcsICdoZXgnKVxufVxuZXhwb3J0c1snUlNBLU1ENSddID0gZXhwb3J0cy5tZDVXaXRoUlNBRW5jcnlwdGlvbiA9IHtcbiAgc2lnbjogJ3JzYScsXG4gIGhhc2g6ICdtZDUnLFxuICBpZDogbmV3IEJ1ZmZlcignMzAyMDMwMGMwNjA4MmE4NjQ4ODZmNzBkMDIwNTA1MDAwNDEwJywgJ2hleCcpXG59XG4iLCJ2YXIgX2FsZ29zID0gcmVxdWlyZSgnLi9hbGdvcycpXG52YXIgY3JlYXRlSGFzaCA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoJylcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBzaWduID0gcmVxdWlyZSgnLi9zaWduJylcbnZhciBzdHJlYW0gPSByZXF1aXJlKCdzdHJlYW0nKVxudmFyIHZlcmlmeSA9IHJlcXVpcmUoJy4vdmVyaWZ5JylcblxudmFyIGFsZ29zID0ge31cbk9iamVjdC5rZXlzKF9hbGdvcykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gIGFsZ29zW2tleV0gPSBhbGdvc1trZXkudG9Mb3dlckNhc2UoKV0gPSBfYWxnb3Nba2V5XVxufSlcblxuZnVuY3Rpb24gU2lnbiAoYWxnb3JpdGhtKSB7XG4gIHN0cmVhbS5Xcml0YWJsZS5jYWxsKHRoaXMpXG5cbiAgdmFyIGRhdGEgPSBhbGdvc1thbGdvcml0aG1dXG4gIGlmICghZGF0YSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBtZXNzYWdlIGRpZ2VzdCcpXG4gIH1cblxuICB0aGlzLl9oYXNoVHlwZSA9IGRhdGEuaGFzaFxuICB0aGlzLl9oYXNoID0gY3JlYXRlSGFzaChkYXRhLmhhc2gpXG4gIHRoaXMuX3RhZyA9IGRhdGEuaWRcbiAgdGhpcy5fc2lnblR5cGUgPSBkYXRhLnNpZ25cbn1cbmluaGVyaXRzKFNpZ24sIHN0cmVhbS5Xcml0YWJsZSlcblxuU2lnbi5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24gX3dyaXRlIChkYXRhLCBfLCBkb25lKSB7XG4gIHRoaXMuX2hhc2gudXBkYXRlKGRhdGEpXG4gIGRvbmUoKVxufVxuXG5TaWduLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUgKGRhdGEsIGVuYykge1xuICBpZiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgZGF0YSA9IG5ldyBCdWZmZXIoZGF0YSwgZW5jKVxuICB9XG5cbiAgdGhpcy5faGFzaC51cGRhdGUoZGF0YSlcbiAgcmV0dXJuIHRoaXNcbn1cblxuU2lnbi5wcm90b3R5cGUuc2lnbiA9IGZ1bmN0aW9uIHNpZ25NZXRob2QgKGtleSwgZW5jKSB7XG4gIHRoaXMuZW5kKClcbiAgdmFyIGhhc2ggPSB0aGlzLl9oYXNoLmRpZ2VzdCgpXG4gIHZhciBzaWcgPSBzaWduKEJ1ZmZlci5jb25jYXQoW3RoaXMuX3RhZywgaGFzaF0pLCBrZXksIHRoaXMuX2hhc2hUeXBlLCB0aGlzLl9zaWduVHlwZSlcblxuICByZXR1cm4gZW5jID8gc2lnLnRvU3RyaW5nKGVuYykgOiBzaWdcbn1cblxuZnVuY3Rpb24gVmVyaWZ5IChhbGdvcml0aG0pIHtcbiAgc3RyZWFtLldyaXRhYmxlLmNhbGwodGhpcylcblxuICB2YXIgZGF0YSA9IGFsZ29zW2FsZ29yaXRobV1cbiAgaWYgKCFkYXRhKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIG1lc3NhZ2UgZGlnZXN0JylcbiAgfVxuXG4gIHRoaXMuX2hhc2ggPSBjcmVhdGVIYXNoKGRhdGEuaGFzaClcbiAgdGhpcy5fdGFnID0gZGF0YS5pZFxuICB0aGlzLl9zaWduVHlwZSA9IGRhdGEuc2lnblxufVxuaW5oZXJpdHMoVmVyaWZ5LCBzdHJlYW0uV3JpdGFibGUpXG5cblZlcmlmeS5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24gX3dyaXRlIChkYXRhLCBfLCBkb25lKSB7XG4gIHRoaXMuX2hhc2gudXBkYXRlKGRhdGEpXG5cbiAgZG9uZSgpXG59XG5cblZlcmlmeS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlIChkYXRhLCBlbmMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIGRhdGEgPSBuZXcgQnVmZmVyKGRhdGEsIGVuYylcbiAgfVxuXG4gIHRoaXMuX2hhc2gudXBkYXRlKGRhdGEpXG4gIHJldHVybiB0aGlzXG59XG5cblZlcmlmeS5wcm90b3R5cGUudmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5TWV0aG9kIChrZXksIHNpZywgZW5jKSB7XG4gIGlmICh0eXBlb2Ygc2lnID09PSAnc3RyaW5nJykge1xuICAgIHNpZyA9IG5ldyBCdWZmZXIoc2lnLCBlbmMpXG4gIH1cblxuICB0aGlzLmVuZCgpXG4gIHZhciBoYXNoID0gdGhpcy5faGFzaC5kaWdlc3QoKVxuXG4gIHJldHVybiB2ZXJpZnkoc2lnLCBCdWZmZXIuY29uY2F0KFt0aGlzLl90YWcsIGhhc2hdKSwga2V5LCB0aGlzLl9zaWduVHlwZSlcbn1cblxuZnVuY3Rpb24gY3JlYXRlU2lnbiAoYWxnb3JpdGhtKSB7XG4gIHJldHVybiBuZXcgU2lnbihhbGdvcml0aG0pXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVZlcmlmeSAoYWxnb3JpdGhtKSB7XG4gIHJldHVybiBuZXcgVmVyaWZ5KGFsZ29yaXRobSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIFNpZ246IGNyZWF0ZVNpZ24sXG4gIFZlcmlmeTogY3JlYXRlVmVyaWZ5LFxuICBjcmVhdGVTaWduOiBjcmVhdGVTaWduLFxuICBjcmVhdGVWZXJpZnk6IGNyZWF0ZVZlcmlmeVxufVxuIiwiJ3VzZSBzdHJpY3QnXG5leHBvcnRzWycxLjMuMTMyLjAuMTAnXSA9ICdzZWNwMjU2azEnXG5cbmV4cG9ydHNbJzEuMy4xMzIuMC4zMyddID0gJ3AyMjQnXG5cbmV4cG9ydHNbJzEuMi44NDAuMTAwNDUuMy4xLjEnXSA9ICdwMTkyJ1xuXG5leHBvcnRzWycxLjIuODQwLjEwMDQ1LjMuMS43J10gPSAncDI1NidcblxuZXhwb3J0c1snMS4zLjEzMi4wLjM0J10gPSAncDM4NCdcblxuZXhwb3J0c1snMS4zLjEzMi4wLjM1J10gPSAncDUyMSdcbiIsIihmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvLyBVdGlsc1xuICBmdW5jdGlvbiBhc3NlcnQgKHZhbCwgbXNnKSB7XG4gICAgaWYgKCF2YWwpIHRocm93IG5ldyBFcnJvcihtc2cgfHwgJ0Fzc2VydGlvbiBmYWlsZWQnKTtcbiAgfVxuXG4gIC8vIENvdWxkIHVzZSBgaW5oZXJpdHNgIG1vZHVsZSwgYnV0IGRvbid0IHdhbnQgdG8gbW92ZSBmcm9tIHNpbmdsZSBmaWxlXG4gIC8vIGFyY2hpdGVjdHVyZSB5ZXQuXG4gIGZ1bmN0aW9uIGluaGVyaXRzIChjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvcjtcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlO1xuICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKCk7XG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yO1xuICB9XG5cbiAgLy8gQk5cblxuICBmdW5jdGlvbiBCTiAobnVtYmVyLCBiYXNlLCBlbmRpYW4pIHtcbiAgICAvLyBNYXkgYmUgYG5ldyBCTihibilgID9cbiAgICBpZiAobnVtYmVyICE9PSBudWxsICYmXG4gICAgICB0eXBlb2YgbnVtYmVyID09PSAnb2JqZWN0JyAmJlxuICAgICAgQXJyYXkuaXNBcnJheShudW1iZXIud29yZHMpKSB7XG4gICAgICByZXR1cm4gbnVtYmVyO1xuICAgIH1cblxuICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgIHRoaXMud29yZHMgPSBudWxsO1xuICAgIHRoaXMubGVuZ3RoID0gMDtcblxuICAgIC8vIFJlZHVjdGlvbiBjb250ZXh0XG4gICAgdGhpcy5yZWQgPSBudWxsO1xuXG4gICAgaWYgKG51bWJlciAhPT0gbnVsbCkge1xuICAgICAgaWYgKGJhc2UgPT09ICdsZScgfHwgYmFzZSA9PT0gJ2JlJykge1xuICAgICAgICBlbmRpYW4gPSBiYXNlO1xuICAgICAgICBiYXNlID0gMTA7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2luaXQobnVtYmVyIHx8IDAsIGJhc2UgfHwgMTAsIGVuZGlhbiB8fCAnYmUnKTtcbiAgICB9XG4gIH1cbiAgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBCTjtcbiAgfSBlbHNlIHtcbiAgICBleHBvcnRzLkJOID0gQk47XG4gIH1cblxuICBCTi5CTiA9IEJOO1xuICBCTi53b3JkU2l6ZSA9IDI2O1xuXG4gIHZhciBCdWZmZXI7XG4gIHRyeSB7XG4gICAgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuICB9IGNhdGNoIChlKSB7XG4gIH1cblxuICBCTi5tYXggPSBmdW5jdGlvbiBtYXggKGxlZnQsIHJpZ2h0KSB7XG4gICAgaWYgKGxlZnQuY21wKHJpZ2h0KSA+IDApIHJldHVybiBsZWZ0O1xuICAgIHJldHVybiByaWdodDtcbiAgfTtcblxuICBCTi5taW4gPSBmdW5jdGlvbiBtaW4gKGxlZnQsIHJpZ2h0KSB7XG4gICAgaWYgKGxlZnQuY21wKHJpZ2h0KSA8IDApIHJldHVybiBsZWZ0O1xuICAgIHJldHVybiByaWdodDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiBpbml0IChudW1iZXIsIGJhc2UsIGVuZGlhbikge1xuICAgIGlmICh0eXBlb2YgbnVtYmVyID09PSAnbnVtYmVyJykge1xuICAgICAgcmV0dXJuIHRoaXMuX2luaXROdW1iZXIobnVtYmVyLCBiYXNlLCBlbmRpYW4pO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgbnVtYmVyID09PSAnb2JqZWN0Jykge1xuICAgICAgcmV0dXJuIHRoaXMuX2luaXRBcnJheShudW1iZXIsIGJhc2UsIGVuZGlhbik7XG4gICAgfVxuXG4gICAgaWYgKGJhc2UgPT09ICdoZXgnKSB7XG4gICAgICBiYXNlID0gMTY7XG4gICAgfVxuICAgIGFzc2VydChiYXNlID09PSAoYmFzZSB8IDApICYmIGJhc2UgPj0gMiAmJiBiYXNlIDw9IDM2KTtcblxuICAgIG51bWJlciA9IG51bWJlci50b1N0cmluZygpLnJlcGxhY2UoL1xccysvZywgJycpO1xuICAgIHZhciBzdGFydCA9IDA7XG4gICAgaWYgKG51bWJlclswXSA9PT0gJy0nKSB7XG4gICAgICBzdGFydCsrO1xuICAgIH1cblxuICAgIGlmIChiYXNlID09PSAxNikge1xuICAgICAgdGhpcy5fcGFyc2VIZXgobnVtYmVyLCBzdGFydCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3BhcnNlQmFzZShudW1iZXIsIGJhc2UsIHN0YXJ0KTtcbiAgICB9XG5cbiAgICBpZiAobnVtYmVyWzBdID09PSAnLScpIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAxO1xuICAgIH1cblxuICAgIHRoaXMuc3RyaXAoKTtcblxuICAgIGlmIChlbmRpYW4gIT09ICdsZScpIHJldHVybjtcblxuICAgIHRoaXMuX2luaXRBcnJheSh0aGlzLnRvQXJyYXkoKSwgYmFzZSwgZW5kaWFuKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuX2luaXROdW1iZXIgPSBmdW5jdGlvbiBfaW5pdE51bWJlciAobnVtYmVyLCBiYXNlLCBlbmRpYW4pIHtcbiAgICBpZiAobnVtYmVyIDwgMCkge1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDE7XG4gICAgICBudW1iZXIgPSAtbnVtYmVyO1xuICAgIH1cbiAgICBpZiAobnVtYmVyIDwgMHg0MDAwMDAwKSB7XG4gICAgICB0aGlzLndvcmRzID0gWyBudW1iZXIgJiAweDNmZmZmZmYgXTtcbiAgICAgIHRoaXMubGVuZ3RoID0gMTtcbiAgICB9IGVsc2UgaWYgKG51bWJlciA8IDB4MTAwMDAwMDAwMDAwMDApIHtcbiAgICAgIHRoaXMud29yZHMgPSBbXG4gICAgICAgIG51bWJlciAmIDB4M2ZmZmZmZixcbiAgICAgICAgKG51bWJlciAvIDB4NDAwMDAwMCkgJiAweDNmZmZmZmZcbiAgICAgIF07XG4gICAgICB0aGlzLmxlbmd0aCA9IDI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFzc2VydChudW1iZXIgPCAweDIwMDAwMDAwMDAwMDAwKTsgLy8gMiBeIDUzICh1bnNhZmUpXG4gICAgICB0aGlzLndvcmRzID0gW1xuICAgICAgICBudW1iZXIgJiAweDNmZmZmZmYsXG4gICAgICAgIChudW1iZXIgLyAweDQwMDAwMDApICYgMHgzZmZmZmZmLFxuICAgICAgICAxXG4gICAgICBdO1xuICAgICAgdGhpcy5sZW5ndGggPSAzO1xuICAgIH1cblxuICAgIGlmIChlbmRpYW4gIT09ICdsZScpIHJldHVybjtcblxuICAgIC8vIFJldmVyc2UgdGhlIGJ5dGVzXG4gICAgdGhpcy5faW5pdEFycmF5KHRoaXMudG9BcnJheSgpLCBiYXNlLCBlbmRpYW4pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5faW5pdEFycmF5ID0gZnVuY3Rpb24gX2luaXRBcnJheSAobnVtYmVyLCBiYXNlLCBlbmRpYW4pIHtcbiAgICAvLyBQZXJoYXBzIGEgVWludDhBcnJheVxuICAgIGFzc2VydCh0eXBlb2YgbnVtYmVyLmxlbmd0aCA9PT0gJ251bWJlcicpO1xuICAgIGlmIChudW1iZXIubGVuZ3RoIDw9IDApIHtcbiAgICAgIHRoaXMud29yZHMgPSBbIDAgXTtcbiAgICAgIHRoaXMubGVuZ3RoID0gMTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHRoaXMubGVuZ3RoID0gTWF0aC5jZWlsKG51bWJlci5sZW5ndGggLyAzKTtcbiAgICB0aGlzLndvcmRzID0gbmV3IEFycmF5KHRoaXMubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMud29yZHNbaV0gPSAwO1xuICAgIH1cblxuICAgIHZhciBqLCB3O1xuICAgIHZhciBvZmYgPSAwO1xuICAgIGlmIChlbmRpYW4gPT09ICdiZScpIHtcbiAgICAgIGZvciAoaSA9IG51bWJlci5sZW5ndGggLSAxLCBqID0gMDsgaSA+PSAwOyBpIC09IDMpIHtcbiAgICAgICAgdyA9IG51bWJlcltpXSB8IChudW1iZXJbaSAtIDFdIDw8IDgpIHwgKG51bWJlcltpIC0gMl0gPDwgMTYpO1xuICAgICAgICB0aGlzLndvcmRzW2pdIHw9ICh3IDw8IG9mZikgJiAweDNmZmZmZmY7XG4gICAgICAgIHRoaXMud29yZHNbaiArIDFdID0gKHcgPj4+ICgyNiAtIG9mZikpICYgMHgzZmZmZmZmO1xuICAgICAgICBvZmYgKz0gMjQ7XG4gICAgICAgIGlmIChvZmYgPj0gMjYpIHtcbiAgICAgICAgICBvZmYgLT0gMjY7XG4gICAgICAgICAgaisrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChlbmRpYW4gPT09ICdsZScpIHtcbiAgICAgIGZvciAoaSA9IDAsIGogPSAwOyBpIDwgbnVtYmVyLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgICAgIHcgPSBudW1iZXJbaV0gfCAobnVtYmVyW2kgKyAxXSA8PCA4KSB8IChudW1iZXJbaSArIDJdIDw8IDE2KTtcbiAgICAgICAgdGhpcy53b3Jkc1tqXSB8PSAodyA8PCBvZmYpICYgMHgzZmZmZmZmO1xuICAgICAgICB0aGlzLndvcmRzW2ogKyAxXSA9ICh3ID4+PiAoMjYgLSBvZmYpKSAmIDB4M2ZmZmZmZjtcbiAgICAgICAgb2ZmICs9IDI0O1xuICAgICAgICBpZiAob2ZmID49IDI2KSB7XG4gICAgICAgICAgb2ZmIC09IDI2O1xuICAgICAgICAgIGorKztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHBhcnNlSGV4IChzdHIsIHN0YXJ0LCBlbmQpIHtcbiAgICB2YXIgciA9IDA7XG4gICAgdmFyIGxlbiA9IE1hdGgubWluKHN0ci5sZW5ndGgsIGVuZCk7XG4gICAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIHZhciBjID0gc3RyLmNoYXJDb2RlQXQoaSkgLSA0ODtcblxuICAgICAgciA8PD0gNDtcblxuICAgICAgLy8gJ2EnIC0gJ2YnXG4gICAgICBpZiAoYyA+PSA0OSAmJiBjIDw9IDU0KSB7XG4gICAgICAgIHIgfD0gYyAtIDQ5ICsgMHhhO1xuXG4gICAgICAvLyAnQScgLSAnRidcbiAgICAgIH0gZWxzZSBpZiAoYyA+PSAxNyAmJiBjIDw9IDIyKSB7XG4gICAgICAgIHIgfD0gYyAtIDE3ICsgMHhhO1xuXG4gICAgICAvLyAnMCcgLSAnOSdcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHIgfD0gYyAmIDB4ZjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHI7XG4gIH1cblxuICBCTi5wcm90b3R5cGUuX3BhcnNlSGV4ID0gZnVuY3Rpb24gX3BhcnNlSGV4IChudW1iZXIsIHN0YXJ0KSB7XG4gICAgLy8gQ3JlYXRlIHBvc3NpYmx5IGJpZ2dlciBhcnJheSB0byBlbnN1cmUgdGhhdCBpdCBmaXRzIHRoZSBudW1iZXJcbiAgICB0aGlzLmxlbmd0aCA9IE1hdGguY2VpbCgobnVtYmVyLmxlbmd0aCAtIHN0YXJ0KSAvIDYpO1xuICAgIHRoaXMud29yZHMgPSBuZXcgQXJyYXkodGhpcy5sZW5ndGgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IDA7XG4gICAgfVxuXG4gICAgdmFyIGosIHc7XG4gICAgLy8gU2NhbiAyNC1iaXQgY2h1bmtzIGFuZCBhZGQgdGhlbSB0byB0aGUgbnVtYmVyXG4gICAgdmFyIG9mZiA9IDA7XG4gICAgZm9yIChpID0gbnVtYmVyLmxlbmd0aCAtIDYsIGogPSAwOyBpID49IHN0YXJ0OyBpIC09IDYpIHtcbiAgICAgIHcgPSBwYXJzZUhleChudW1iZXIsIGksIGkgKyA2KTtcbiAgICAgIHRoaXMud29yZHNbal0gfD0gKHcgPDwgb2ZmKSAmIDB4M2ZmZmZmZjtcbiAgICAgIHRoaXMud29yZHNbaiArIDFdIHw9IHcgPj4+ICgyNiAtIG9mZikgJiAweDNmZmZmZjtcbiAgICAgIG9mZiArPSAyNDtcbiAgICAgIGlmIChvZmYgPj0gMjYpIHtcbiAgICAgICAgb2ZmIC09IDI2O1xuICAgICAgICBqKys7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpICsgNiAhPT0gc3RhcnQpIHtcbiAgICAgIHcgPSBwYXJzZUhleChudW1iZXIsIHN0YXJ0LCBpICsgNik7XG4gICAgICB0aGlzLndvcmRzW2pdIHw9ICh3IDw8IG9mZikgJiAweDNmZmZmZmY7XG4gICAgICB0aGlzLndvcmRzW2ogKyAxXSB8PSB3ID4+PiAoMjYgLSBvZmYpICYgMHgzZmZmZmY7XG4gICAgfVxuICAgIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBmdW5jdGlvbiBwYXJzZUJhc2UgKHN0ciwgc3RhcnQsIGVuZCwgbXVsKSB7XG4gICAgdmFyIHIgPSAwO1xuICAgIHZhciBsZW4gPSBNYXRoLm1pbihzdHIubGVuZ3RoLCBlbmQpO1xuICAgIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICB2YXIgYyA9IHN0ci5jaGFyQ29kZUF0KGkpIC0gNDg7XG5cbiAgICAgIHIgKj0gbXVsO1xuXG4gICAgICAvLyAnYSdcbiAgICAgIGlmIChjID49IDQ5KSB7XG4gICAgICAgIHIgKz0gYyAtIDQ5ICsgMHhhO1xuXG4gICAgICAvLyAnQSdcbiAgICAgIH0gZWxzZSBpZiAoYyA+PSAxNykge1xuICAgICAgICByICs9IGMgLSAxNyArIDB4YTtcblxuICAgICAgLy8gJzAnIC0gJzknXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByICs9IGM7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByO1xuICB9XG5cbiAgQk4ucHJvdG90eXBlLl9wYXJzZUJhc2UgPSBmdW5jdGlvbiBfcGFyc2VCYXNlIChudW1iZXIsIGJhc2UsIHN0YXJ0KSB7XG4gICAgLy8gSW5pdGlhbGl6ZSBhcyB6ZXJvXG4gICAgdGhpcy53b3JkcyA9IFsgMCBdO1xuICAgIHRoaXMubGVuZ3RoID0gMTtcblxuICAgIC8vIEZpbmQgbGVuZ3RoIG9mIGxpbWIgaW4gYmFzZVxuICAgIGZvciAodmFyIGxpbWJMZW4gPSAwLCBsaW1iUG93ID0gMTsgbGltYlBvdyA8PSAweDNmZmZmZmY7IGxpbWJQb3cgKj0gYmFzZSkge1xuICAgICAgbGltYkxlbisrO1xuICAgIH1cbiAgICBsaW1iTGVuLS07XG4gICAgbGltYlBvdyA9IChsaW1iUG93IC8gYmFzZSkgfCAwO1xuXG4gICAgdmFyIHRvdGFsID0gbnVtYmVyLmxlbmd0aCAtIHN0YXJ0O1xuICAgIHZhciBtb2QgPSB0b3RhbCAlIGxpbWJMZW47XG4gICAgdmFyIGVuZCA9IE1hdGgubWluKHRvdGFsLCB0b3RhbCAtIG1vZCkgKyBzdGFydDtcblxuICAgIHZhciB3b3JkID0gMDtcbiAgICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkgKz0gbGltYkxlbikge1xuICAgICAgd29yZCA9IHBhcnNlQmFzZShudW1iZXIsIGksIGkgKyBsaW1iTGVuLCBiYXNlKTtcblxuICAgICAgdGhpcy5pbXVsbihsaW1iUG93KTtcbiAgICAgIGlmICh0aGlzLndvcmRzWzBdICsgd29yZCA8IDB4NDAwMDAwMCkge1xuICAgICAgICB0aGlzLndvcmRzWzBdICs9IHdvcmQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9pYWRkbih3b3JkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobW9kICE9PSAwKSB7XG4gICAgICB2YXIgcG93ID0gMTtcbiAgICAgIHdvcmQgPSBwYXJzZUJhc2UobnVtYmVyLCBpLCBudW1iZXIubGVuZ3RoLCBiYXNlKTtcblxuICAgICAgZm9yIChpID0gMDsgaSA8IG1vZDsgaSsrKSB7XG4gICAgICAgIHBvdyAqPSBiYXNlO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmltdWxuKHBvdyk7XG4gICAgICBpZiAodGhpcy53b3Jkc1swXSArIHdvcmQgPCAweDQwMDAwMDApIHtcbiAgICAgICAgdGhpcy53b3Jkc1swXSArPSB3b3JkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5faWFkZG4od29yZCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gY29weSAoZGVzdCkge1xuICAgIGRlc3Qud29yZHMgPSBuZXcgQXJyYXkodGhpcy5sZW5ndGgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgZGVzdC53b3Jkc1tpXSA9IHRoaXMud29yZHNbaV07XG4gICAgfVxuICAgIGRlc3QubGVuZ3RoID0gdGhpcy5sZW5ndGg7XG4gICAgZGVzdC5uZWdhdGl2ZSA9IHRoaXMubmVnYXRpdmU7XG4gICAgZGVzdC5yZWQgPSB0aGlzLnJlZDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiBjbG9uZSAoKSB7XG4gICAgdmFyIHIgPSBuZXcgQk4obnVsbCk7XG4gICAgdGhpcy5jb3B5KHIpO1xuICAgIHJldHVybiByO1xuICB9O1xuXG4gIC8vIFJlbW92ZSBsZWFkaW5nIGAwYCBmcm9tIGB0aGlzYFxuICBCTi5wcm90b3R5cGUuc3RyaXAgPSBmdW5jdGlvbiBzdHJpcCAoKSB7XG4gICAgd2hpbGUgKHRoaXMubGVuZ3RoID4gMSAmJiB0aGlzLndvcmRzW3RoaXMubGVuZ3RoIC0gMV0gPT09IDApIHtcbiAgICAgIHRoaXMubGVuZ3RoLS07XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9ub3JtU2lnbigpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5fbm9ybVNpZ24gPSBmdW5jdGlvbiBfbm9ybVNpZ24gKCkge1xuICAgIC8vIC0wID0gMFxuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMSAmJiB0aGlzLndvcmRzWzBdID09PSAwKSB7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgICByZXR1cm4gKHRoaXMucmVkID8gJzxCTi1SOiAnIDogJzxCTjogJykgKyB0aGlzLnRvU3RyaW5nKDE2KSArICc+JztcbiAgfTtcblxuICAvKlxuXG4gIHZhciB6ZXJvcyA9IFtdO1xuICB2YXIgZ3JvdXBTaXplcyA9IFtdO1xuICB2YXIgZ3JvdXBCYXNlcyA9IFtdO1xuXG4gIHZhciBzID0gJyc7XG4gIHZhciBpID0gLTE7XG4gIHdoaWxlICgrK2kgPCBCTi53b3JkU2l6ZSkge1xuICAgIHplcm9zW2ldID0gcztcbiAgICBzICs9ICcwJztcbiAgfVxuICBncm91cFNpemVzWzBdID0gMDtcbiAgZ3JvdXBTaXplc1sxXSA9IDA7XG4gIGdyb3VwQmFzZXNbMF0gPSAwO1xuICBncm91cEJhc2VzWzFdID0gMDtcbiAgdmFyIGJhc2UgPSAyIC0gMTtcbiAgd2hpbGUgKCsrYmFzZSA8IDM2ICsgMSkge1xuICAgIHZhciBncm91cFNpemUgPSAwO1xuICAgIHZhciBncm91cEJhc2UgPSAxO1xuICAgIHdoaWxlIChncm91cEJhc2UgPCAoMSA8PCBCTi53b3JkU2l6ZSkgLyBiYXNlKSB7XG4gICAgICBncm91cEJhc2UgKj0gYmFzZTtcbiAgICAgIGdyb3VwU2l6ZSArPSAxO1xuICAgIH1cbiAgICBncm91cFNpemVzW2Jhc2VdID0gZ3JvdXBTaXplO1xuICAgIGdyb3VwQmFzZXNbYmFzZV0gPSBncm91cEJhc2U7XG4gIH1cblxuICAqL1xuXG4gIHZhciB6ZXJvcyA9IFtcbiAgICAnJyxcbiAgICAnMCcsXG4gICAgJzAwJyxcbiAgICAnMDAwJyxcbiAgICAnMDAwMCcsXG4gICAgJzAwMDAwJyxcbiAgICAnMDAwMDAwJyxcbiAgICAnMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAnMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCdcbiAgXTtcblxuICB2YXIgZ3JvdXBTaXplcyA9IFtcbiAgICAwLCAwLFxuICAgIDI1LCAxNiwgMTIsIDExLCAxMCwgOSwgOCxcbiAgICA4LCA3LCA3LCA3LCA3LCA2LCA2LFxuICAgIDYsIDYsIDYsIDYsIDYsIDUsIDUsXG4gICAgNSwgNSwgNSwgNSwgNSwgNSwgNSxcbiAgICA1LCA1LCA1LCA1LCA1LCA1LCA1XG4gIF07XG5cbiAgdmFyIGdyb3VwQmFzZXMgPSBbXG4gICAgMCwgMCxcbiAgICAzMzU1NDQzMiwgNDMwNDY3MjEsIDE2Nzc3MjE2LCA0ODgyODEyNSwgNjA0NjYxNzYsIDQwMzUzNjA3LCAxNjc3NzIxNixcbiAgICA0MzA0NjcyMSwgMTAwMDAwMDAsIDE5NDg3MTcxLCAzNTgzMTgwOCwgNjI3NDg1MTcsIDc1Mjk1MzYsIDExMzkwNjI1LFxuICAgIDE2Nzc3MjE2LCAyNDEzNzU2OSwgMzQwMTIyMjQsIDQ3MDQ1ODgxLCA2NDAwMDAwMCwgNDA4NDEwMSwgNTE1MzYzMixcbiAgICA2NDM2MzQzLCA3OTYyNjI0LCA5NzY1NjI1LCAxMTg4MTM3NiwgMTQzNDg5MDcsIDE3MjEwMzY4LCAyMDUxMTE0OSxcbiAgICAyNDMwMDAwMCwgMjg2MjkxNTEsIDMzNTU0NDMyLCAzOTEzNTM5MywgNDU0MzU0MjQsIDUyNTIxODc1LCA2MDQ2NjE3NlxuICBdO1xuXG4gIEJOLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nIChiYXNlLCBwYWRkaW5nKSB7XG4gICAgYmFzZSA9IGJhc2UgfHwgMTA7XG4gICAgcGFkZGluZyA9IHBhZGRpbmcgfCAwIHx8IDE7XG5cbiAgICB2YXIgb3V0O1xuICAgIGlmIChiYXNlID09PSAxNiB8fCBiYXNlID09PSAnaGV4Jykge1xuICAgICAgb3V0ID0gJyc7XG4gICAgICB2YXIgb2ZmID0gMDtcbiAgICAgIHZhciBjYXJyeSA9IDA7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHcgPSB0aGlzLndvcmRzW2ldO1xuICAgICAgICB2YXIgd29yZCA9ICgoKHcgPDwgb2ZmKSB8IGNhcnJ5KSAmIDB4ZmZmZmZmKS50b1N0cmluZygxNik7XG4gICAgICAgIGNhcnJ5ID0gKHcgPj4+ICgyNCAtIG9mZikpICYgMHhmZmZmZmY7XG4gICAgICAgIGlmIChjYXJyeSAhPT0gMCB8fCBpICE9PSB0aGlzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICBvdXQgPSB6ZXJvc1s2IC0gd29yZC5sZW5ndGhdICsgd29yZCArIG91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvdXQgPSB3b3JkICsgb3V0O1xuICAgICAgICB9XG4gICAgICAgIG9mZiArPSAyO1xuICAgICAgICBpZiAob2ZmID49IDI2KSB7XG4gICAgICAgICAgb2ZmIC09IDI2O1xuICAgICAgICAgIGktLTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGNhcnJ5ICE9PSAwKSB7XG4gICAgICAgIG91dCA9IGNhcnJ5LnRvU3RyaW5nKDE2KSArIG91dDtcbiAgICAgIH1cbiAgICAgIHdoaWxlIChvdXQubGVuZ3RoICUgcGFkZGluZyAhPT0gMCkge1xuICAgICAgICBvdXQgPSAnMCcgKyBvdXQ7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgICBvdXQgPSAnLScgKyBvdXQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gb3V0O1xuICAgIH1cblxuICAgIGlmIChiYXNlID09PSAoYmFzZSB8IDApICYmIGJhc2UgPj0gMiAmJiBiYXNlIDw9IDM2KSB7XG4gICAgICAvLyB2YXIgZ3JvdXBTaXplID0gTWF0aC5mbG9vcihCTi53b3JkU2l6ZSAqIE1hdGguTE4yIC8gTWF0aC5sb2coYmFzZSkpO1xuICAgICAgdmFyIGdyb3VwU2l6ZSA9IGdyb3VwU2l6ZXNbYmFzZV07XG4gICAgICAvLyB2YXIgZ3JvdXBCYXNlID0gTWF0aC5wb3coYmFzZSwgZ3JvdXBTaXplKTtcbiAgICAgIHZhciBncm91cEJhc2UgPSBncm91cEJhc2VzW2Jhc2VdO1xuICAgICAgb3V0ID0gJyc7XG4gICAgICB2YXIgYyA9IHRoaXMuY2xvbmUoKTtcbiAgICAgIGMubmVnYXRpdmUgPSAwO1xuICAgICAgd2hpbGUgKCFjLmlzWmVybygpKSB7XG4gICAgICAgIHZhciByID0gYy5tb2RuKGdyb3VwQmFzZSkudG9TdHJpbmcoYmFzZSk7XG4gICAgICAgIGMgPSBjLmlkaXZuKGdyb3VwQmFzZSk7XG5cbiAgICAgICAgaWYgKCFjLmlzWmVybygpKSB7XG4gICAgICAgICAgb3V0ID0gemVyb3NbZ3JvdXBTaXplIC0gci5sZW5ndGhdICsgciArIG91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvdXQgPSByICsgb3V0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5pc1plcm8oKSkge1xuICAgICAgICBvdXQgPSAnMCcgKyBvdXQ7XG4gICAgICB9XG4gICAgICB3aGlsZSAob3V0Lmxlbmd0aCAlIHBhZGRpbmcgIT09IDApIHtcbiAgICAgICAgb3V0ID0gJzAnICsgb3V0O1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDApIHtcbiAgICAgICAgb3V0ID0gJy0nICsgb3V0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG91dDtcbiAgICB9XG5cbiAgICBhc3NlcnQoZmFsc2UsICdCYXNlIHNob3VsZCBiZSBiZXR3ZWVuIDIgYW5kIDM2Jyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnRvTnVtYmVyID0gZnVuY3Rpb24gdG9OdW1iZXIgKCkge1xuICAgIHZhciBsZW5ndGggPSB0aGlzLmJpdExlbmd0aCgpO1xuICAgIHZhciByZXQ7XG4gICAgaWYgKGxlbmd0aCA8PSAyNikge1xuICAgICAgcmV0ID0gdGhpcy53b3Jkc1swXTtcbiAgICB9IGVsc2UgaWYgKGxlbmd0aCA8PSA1Mikge1xuICAgICAgcmV0ID0gKHRoaXMud29yZHNbMV0gKiAweDQwMDAwMDApICsgdGhpcy53b3Jkc1swXTtcbiAgICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gNTMpIHtcbiAgICAgIC8vIE5PVEU6IGF0IHRoaXMgc3RhZ2UgaXQgaXMga25vd24gdGhhdCB0aGUgdG9wIGJpdCBpcyBzZXRcbiAgICAgIHJldCA9IDB4MTAwMDAwMDAwMDAwMDAgKyAodGhpcy53b3Jkc1sxXSAqIDB4NDAwMDAwMCkgKyB0aGlzLndvcmRzWzBdO1xuICAgIH0gZWxzZSB7XG4gICAgICBhc3NlcnQoZmFsc2UsICdOdW1iZXIgY2FuIG9ubHkgc2FmZWx5IHN0b3JlIHVwIHRvIDUzIGJpdHMnKTtcbiAgICB9XG4gICAgcmV0dXJuICh0aGlzLm5lZ2F0aXZlICE9PSAwKSA/IC1yZXQgOiByZXQ7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG9TdHJpbmcoMTYpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS50b0J1ZmZlciA9IGZ1bmN0aW9uIHRvQnVmZmVyIChlbmRpYW4sIGxlbmd0aCkge1xuICAgIGFzc2VydCh0eXBlb2YgQnVmZmVyICE9PSAndW5kZWZpbmVkJyk7XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIodGhpcy50b0FycmF5KGVuZGlhbiwgbGVuZ3RoKSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnRvQXJyYXkgPSBmdW5jdGlvbiB0b0FycmF5IChlbmRpYW4sIGxlbmd0aCkge1xuICAgIHZhciBieXRlTGVuZ3RoID0gdGhpcy5ieXRlTGVuZ3RoKCk7XG4gICAgdmFyIHJlcUxlbmd0aCA9IGxlbmd0aCB8fCBNYXRoLm1heCgxLCBieXRlTGVuZ3RoKTtcbiAgICBhc3NlcnQoYnl0ZUxlbmd0aCA8PSByZXFMZW5ndGgsICdieXRlIGFycmF5IGxvbmdlciB0aGFuIGRlc2lyZWQgbGVuZ3RoJyk7XG4gICAgYXNzZXJ0KHJlcUxlbmd0aCA+IDAsICdSZXF1ZXN0ZWQgYXJyYXkgbGVuZ3RoIDw9IDAnKTtcblxuICAgIHRoaXMuc3RyaXAoKTtcbiAgICB2YXIgbGl0dGxlRW5kaWFuID0gZW5kaWFuID09PSAnbGUnO1xuICAgIHZhciByZXMgPSBuZXcgQXJyYXkocmVxTGVuZ3RoKTtcblxuICAgIHZhciBiLCBpO1xuICAgIHZhciBxID0gdGhpcy5jbG9uZSgpO1xuICAgIGlmICghbGl0dGxlRW5kaWFuKSB7XG4gICAgICAvLyBBc3N1bWUgYmlnLWVuZGlhblxuICAgICAgZm9yIChpID0gMDsgaSA8IHJlcUxlbmd0aCAtIGJ5dGVMZW5ndGg7IGkrKykge1xuICAgICAgICByZXNbaV0gPSAwO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGkgPSAwOyAhcS5pc1plcm8oKTsgaSsrKSB7XG4gICAgICAgIGIgPSBxLmFuZGxuKDB4ZmYpO1xuICAgICAgICBxLml1c2hybig4KTtcblxuICAgICAgICByZXNbcmVxTGVuZ3RoIC0gaSAtIDFdID0gYjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChpID0gMDsgIXEuaXNaZXJvKCk7IGkrKykge1xuICAgICAgICBiID0gcS5hbmRsbigweGZmKTtcbiAgICAgICAgcS5pdXNocm4oOCk7XG5cbiAgICAgICAgcmVzW2ldID0gYjtcbiAgICAgIH1cblxuICAgICAgZm9yICg7IGkgPCByZXFMZW5ndGg7IGkrKykge1xuICAgICAgICByZXNbaV0gPSAwO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgaWYgKE1hdGguY2x6MzIpIHtcbiAgICBCTi5wcm90b3R5cGUuX2NvdW50Qml0cyA9IGZ1bmN0aW9uIF9jb3VudEJpdHMgKHcpIHtcbiAgICAgIHJldHVybiAzMiAtIE1hdGguY2x6MzIodyk7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBCTi5wcm90b3R5cGUuX2NvdW50Qml0cyA9IGZ1bmN0aW9uIF9jb3VudEJpdHMgKHcpIHtcbiAgICAgIHZhciB0ID0gdztcbiAgICAgIHZhciByID0gMDtcbiAgICAgIGlmICh0ID49IDB4MTAwMCkge1xuICAgICAgICByICs9IDEzO1xuICAgICAgICB0ID4+Pj0gMTM7XG4gICAgICB9XG4gICAgICBpZiAodCA+PSAweDQwKSB7XG4gICAgICAgIHIgKz0gNztcbiAgICAgICAgdCA+Pj49IDc7XG4gICAgICB9XG4gICAgICBpZiAodCA+PSAweDgpIHtcbiAgICAgICAgciArPSA0O1xuICAgICAgICB0ID4+Pj0gNDtcbiAgICAgIH1cbiAgICAgIGlmICh0ID49IDB4MDIpIHtcbiAgICAgICAgciArPSAyO1xuICAgICAgICB0ID4+Pj0gMjtcbiAgICAgIH1cbiAgICAgIHJldHVybiByICsgdDtcbiAgICB9O1xuICB9XG5cbiAgQk4ucHJvdG90eXBlLl96ZXJvQml0cyA9IGZ1bmN0aW9uIF96ZXJvQml0cyAodykge1xuICAgIC8vIFNob3J0LWN1dFxuICAgIGlmICh3ID09PSAwKSByZXR1cm4gMjY7XG5cbiAgICB2YXIgdCA9IHc7XG4gICAgdmFyIHIgPSAwO1xuICAgIGlmICgodCAmIDB4MWZmZikgPT09IDApIHtcbiAgICAgIHIgKz0gMTM7XG4gICAgICB0ID4+Pj0gMTM7XG4gICAgfVxuICAgIGlmICgodCAmIDB4N2YpID09PSAwKSB7XG4gICAgICByICs9IDc7XG4gICAgICB0ID4+Pj0gNztcbiAgICB9XG4gICAgaWYgKCh0ICYgMHhmKSA9PT0gMCkge1xuICAgICAgciArPSA0O1xuICAgICAgdCA+Pj49IDQ7XG4gICAgfVxuICAgIGlmICgodCAmIDB4MykgPT09IDApIHtcbiAgICAgIHIgKz0gMjtcbiAgICAgIHQgPj4+PSAyO1xuICAgIH1cbiAgICBpZiAoKHQgJiAweDEpID09PSAwKSB7XG4gICAgICByKys7XG4gICAgfVxuICAgIHJldHVybiByO1xuICB9O1xuXG4gIC8vIFJldHVybiBudW1iZXIgb2YgdXNlZCBiaXRzIGluIGEgQk5cbiAgQk4ucHJvdG90eXBlLmJpdExlbmd0aCA9IGZ1bmN0aW9uIGJpdExlbmd0aCAoKSB7XG4gICAgdmFyIHcgPSB0aGlzLndvcmRzW3RoaXMubGVuZ3RoIC0gMV07XG4gICAgdmFyIGhpID0gdGhpcy5fY291bnRCaXRzKHcpO1xuICAgIHJldHVybiAodGhpcy5sZW5ndGggLSAxKSAqIDI2ICsgaGk7XG4gIH07XG5cbiAgZnVuY3Rpb24gdG9CaXRBcnJheSAobnVtKSB7XG4gICAgdmFyIHcgPSBuZXcgQXJyYXkobnVtLmJpdExlbmd0aCgpKTtcblxuICAgIGZvciAodmFyIGJpdCA9IDA7IGJpdCA8IHcubGVuZ3RoOyBiaXQrKykge1xuICAgICAgdmFyIG9mZiA9IChiaXQgLyAyNikgfCAwO1xuICAgICAgdmFyIHdiaXQgPSBiaXQgJSAyNjtcblxuICAgICAgd1tiaXRdID0gKG51bS53b3Jkc1tvZmZdICYgKDEgPDwgd2JpdCkpID4+PiB3Yml0O1xuICAgIH1cblxuICAgIHJldHVybiB3O1xuICB9XG5cbiAgLy8gTnVtYmVyIG9mIHRyYWlsaW5nIHplcm8gYml0c1xuICBCTi5wcm90b3R5cGUuemVyb0JpdHMgPSBmdW5jdGlvbiB6ZXJvQml0cyAoKSB7XG4gICAgaWYgKHRoaXMuaXNaZXJvKCkpIHJldHVybiAwO1xuXG4gICAgdmFyIHIgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGIgPSB0aGlzLl96ZXJvQml0cyh0aGlzLndvcmRzW2ldKTtcbiAgICAgIHIgKz0gYjtcbiAgICAgIGlmIChiICE9PSAyNikgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiByO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5ieXRlTGVuZ3RoID0gZnVuY3Rpb24gYnl0ZUxlbmd0aCAoKSB7XG4gICAgcmV0dXJuIE1hdGguY2VpbCh0aGlzLmJpdExlbmd0aCgpIC8gOCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnRvVHdvcyA9IGZ1bmN0aW9uIHRvVHdvcyAod2lkdGgpIHtcbiAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgcmV0dXJuIHRoaXMuYWJzKCkuaW5vdG4od2lkdGgpLmlhZGRuKDEpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5mcm9tVHdvcyA9IGZ1bmN0aW9uIGZyb21Ud29zICh3aWR0aCkge1xuICAgIGlmICh0aGlzLnRlc3RuKHdpZHRoIC0gMSkpIHtcbiAgICAgIHJldHVybiB0aGlzLm5vdG4od2lkdGgpLmlhZGRuKDEpLmluZWcoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaXNOZWcgPSBmdW5jdGlvbiBpc05lZyAoKSB7XG4gICAgcmV0dXJuIHRoaXMubmVnYXRpdmUgIT09IDA7XG4gIH07XG5cbiAgLy8gUmV0dXJuIG5lZ2F0aXZlIGNsb25lIG9mIGB0aGlzYFxuICBCTi5wcm90b3R5cGUubmVnID0gZnVuY3Rpb24gbmVnICgpIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmluZWcoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaW5lZyA9IGZ1bmN0aW9uIGluZWcgKCkge1xuICAgIGlmICghdGhpcy5pc1plcm8oKSkge1xuICAgICAgdGhpcy5uZWdhdGl2ZSBePSAxO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8vIE9yIGBudW1gIHdpdGggYHRoaXNgIGluLXBsYWNlXG4gIEJOLnByb3RvdHlwZS5pdW9yID0gZnVuY3Rpb24gaXVvciAobnVtKSB7XG4gICAgd2hpbGUgKHRoaXMubGVuZ3RoIDwgbnVtLmxlbmd0aCkge1xuICAgICAgdGhpcy53b3Jkc1t0aGlzLmxlbmd0aCsrXSA9IDA7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW0ubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMud29yZHNbaV0gPSB0aGlzLndvcmRzW2ldIHwgbnVtLndvcmRzW2ldO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmlvciA9IGZ1bmN0aW9uIGlvciAobnVtKSB7XG4gICAgYXNzZXJ0KCh0aGlzLm5lZ2F0aXZlIHwgbnVtLm5lZ2F0aXZlKSA9PT0gMCk7XG4gICAgcmV0dXJuIHRoaXMuaXVvcihudW0pO1xuICB9O1xuXG4gIC8vIE9yIGBudW1gIHdpdGggYHRoaXNgXG4gIEJOLnByb3RvdHlwZS5vciA9IGZ1bmN0aW9uIG9yIChudW0pIHtcbiAgICBpZiAodGhpcy5sZW5ndGggPiBudW0ubGVuZ3RoKSByZXR1cm4gdGhpcy5jbG9uZSgpLmlvcihudW0pO1xuICAgIHJldHVybiBudW0uY2xvbmUoKS5pb3IodGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnVvciA9IGZ1bmN0aW9uIHVvciAobnVtKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkgcmV0dXJuIHRoaXMuY2xvbmUoKS5pdW9yKG51bSk7XG4gICAgcmV0dXJuIG51bS5jbG9uZSgpLml1b3IodGhpcyk7XG4gIH07XG5cbiAgLy8gQW5kIGBudW1gIHdpdGggYHRoaXNgIGluLXBsYWNlXG4gIEJOLnByb3RvdHlwZS5pdWFuZCA9IGZ1bmN0aW9uIGl1YW5kIChudW0pIHtcbiAgICAvLyBiID0gbWluLWxlbmd0aChudW0sIHRoaXMpXG4gICAgdmFyIGI7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkge1xuICAgICAgYiA9IG51bTtcbiAgICB9IGVsc2Uge1xuICAgICAgYiA9IHRoaXM7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBiLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gdGhpcy53b3Jkc1tpXSAmIG51bS53b3Jkc1tpXTtcbiAgICB9XG5cbiAgICB0aGlzLmxlbmd0aCA9IGIubGVuZ3RoO1xuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaWFuZCA9IGZ1bmN0aW9uIGlhbmQgKG51bSkge1xuICAgIGFzc2VydCgodGhpcy5uZWdhdGl2ZSB8IG51bS5uZWdhdGl2ZSkgPT09IDApO1xuICAgIHJldHVybiB0aGlzLml1YW5kKG51bSk7XG4gIH07XG5cbiAgLy8gQW5kIGBudW1gIHdpdGggYHRoaXNgXG4gIEJOLnByb3RvdHlwZS5hbmQgPSBmdW5jdGlvbiBhbmQgKG51bSkge1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHJldHVybiB0aGlzLmNsb25lKCkuaWFuZChudW0pO1xuICAgIHJldHVybiBudW0uY2xvbmUoKS5pYW5kKHRoaXMpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS51YW5kID0gZnVuY3Rpb24gdWFuZCAobnVtKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkgcmV0dXJuIHRoaXMuY2xvbmUoKS5pdWFuZChudW0pO1xuICAgIHJldHVybiBudW0uY2xvbmUoKS5pdWFuZCh0aGlzKTtcbiAgfTtcblxuICAvLyBYb3IgYG51bWAgd2l0aCBgdGhpc2AgaW4tcGxhY2VcbiAgQk4ucHJvdG90eXBlLml1eG9yID0gZnVuY3Rpb24gaXV4b3IgKG51bSkge1xuICAgIC8vIGEubGVuZ3RoID4gYi5sZW5ndGhcbiAgICB2YXIgYTtcbiAgICB2YXIgYjtcbiAgICBpZiAodGhpcy5sZW5ndGggPiBudW0ubGVuZ3RoKSB7XG4gICAgICBhID0gdGhpcztcbiAgICAgIGIgPSBudW07XG4gICAgfSBlbHNlIHtcbiAgICAgIGEgPSBudW07XG4gICAgICBiID0gdGhpcztcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGIubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMud29yZHNbaV0gPSBhLndvcmRzW2ldIF4gYi53b3Jkc1tpXTtcbiAgICB9XG5cbiAgICBpZiAodGhpcyAhPT0gYSkge1xuICAgICAgZm9yICg7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMud29yZHNbaV0gPSBhLndvcmRzW2ldO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMubGVuZ3RoID0gYS5sZW5ndGg7XG5cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5peG9yID0gZnVuY3Rpb24gaXhvciAobnVtKSB7XG4gICAgYXNzZXJ0KCh0aGlzLm5lZ2F0aXZlIHwgbnVtLm5lZ2F0aXZlKSA9PT0gMCk7XG4gICAgcmV0dXJuIHRoaXMuaXV4b3IobnVtKTtcbiAgfTtcblxuICAvLyBYb3IgYG51bWAgd2l0aCBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLnhvciA9IGZ1bmN0aW9uIHhvciAobnVtKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkgcmV0dXJuIHRoaXMuY2xvbmUoKS5peG9yKG51bSk7XG4gICAgcmV0dXJuIG51bS5jbG9uZSgpLml4b3IodGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnV4b3IgPSBmdW5jdGlvbiB1eG9yIChudW0pIHtcbiAgICBpZiAodGhpcy5sZW5ndGggPiBudW0ubGVuZ3RoKSByZXR1cm4gdGhpcy5jbG9uZSgpLml1eG9yKG51bSk7XG4gICAgcmV0dXJuIG51bS5jbG9uZSgpLml1eG9yKHRoaXMpO1xuICB9O1xuXG4gIC8vIE5vdCBgYHRoaXNgYCB3aXRoIGBgd2lkdGhgYCBiaXR3aWR0aFxuICBCTi5wcm90b3R5cGUuaW5vdG4gPSBmdW5jdGlvbiBpbm90biAod2lkdGgpIHtcbiAgICBhc3NlcnQodHlwZW9mIHdpZHRoID09PSAnbnVtYmVyJyAmJiB3aWR0aCA+PSAwKTtcblxuICAgIHZhciBieXRlc05lZWRlZCA9IE1hdGguY2VpbCh3aWR0aCAvIDI2KSB8IDA7XG4gICAgdmFyIGJpdHNMZWZ0ID0gd2lkdGggJSAyNjtcblxuICAgIC8vIEV4dGVuZCB0aGUgYnVmZmVyIHdpdGggbGVhZGluZyB6ZXJvZXNcbiAgICB3aGlsZSAodGhpcy5sZW5ndGggPCBieXRlc05lZWRlZCkge1xuICAgICAgdGhpcy53b3Jkc1t0aGlzLmxlbmd0aCsrXSA9IDA7XG4gICAgfVxuXG4gICAgaWYgKGJpdHNMZWZ0ID4gMCkge1xuICAgICAgYnl0ZXNOZWVkZWQtLTtcbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgY29tcGxldGUgd29yZHNcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzTmVlZGVkOyBpKyspIHtcbiAgICAgIHRoaXMud29yZHNbaV0gPSB+dGhpcy53b3Jkc1tpXSAmIDB4M2ZmZmZmZjtcbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgdGhlIHJlc2lkdWVcbiAgICBpZiAoYml0c0xlZnQgPiAwKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gfnRoaXMud29yZHNbaV0gJiAoMHgzZmZmZmZmID4+ICgyNiAtIGJpdHNMZWZ0KSk7XG4gICAgfVxuXG4gICAgLy8gQW5kIHJlbW92ZSBsZWFkaW5nIHplcm9lc1xuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLm5vdG4gPSBmdW5jdGlvbiBub3RuICh3aWR0aCkge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaW5vdG4od2lkdGgpO1xuICB9O1xuXG4gIC8vIFNldCBgYml0YCBvZiBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLnNldG4gPSBmdW5jdGlvbiBzZXRuIChiaXQsIHZhbCkge1xuICAgIGFzc2VydCh0eXBlb2YgYml0ID09PSAnbnVtYmVyJyAmJiBiaXQgPj0gMCk7XG5cbiAgICB2YXIgb2ZmID0gKGJpdCAvIDI2KSB8IDA7XG4gICAgdmFyIHdiaXQgPSBiaXQgJSAyNjtcblxuICAgIHdoaWxlICh0aGlzLmxlbmd0aCA8PSBvZmYpIHtcbiAgICAgIHRoaXMud29yZHNbdGhpcy5sZW5ndGgrK10gPSAwO1xuICAgIH1cblxuICAgIGlmICh2YWwpIHtcbiAgICAgIHRoaXMud29yZHNbb2ZmXSA9IHRoaXMud29yZHNbb2ZmXSB8ICgxIDw8IHdiaXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLndvcmRzW29mZl0gPSB0aGlzLndvcmRzW29mZl0gJiB+KDEgPDwgd2JpdCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICAvLyBBZGQgYG51bWAgdG8gYHRoaXNgIGluLXBsYWNlXG4gIEJOLnByb3RvdHlwZS5pYWRkID0gZnVuY3Rpb24gaWFkZCAobnVtKSB7XG4gICAgdmFyIHI7XG5cbiAgICAvLyBuZWdhdGl2ZSArIHBvc2l0aXZlXG4gICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDAgJiYgbnVtLm5lZ2F0aXZlID09PSAwKSB7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMDtcbiAgICAgIHIgPSB0aGlzLmlzdWIobnVtKTtcbiAgICAgIHRoaXMubmVnYXRpdmUgXj0gMTtcbiAgICAgIHJldHVybiB0aGlzLl9ub3JtU2lnbigpO1xuXG4gICAgLy8gcG9zaXRpdmUgKyBuZWdhdGl2ZVxuICAgIH0gZWxzZSBpZiAodGhpcy5uZWdhdGl2ZSA9PT0gMCAmJiBudW0ubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIG51bS5uZWdhdGl2ZSA9IDA7XG4gICAgICByID0gdGhpcy5pc3ViKG51bSk7XG4gICAgICBudW0ubmVnYXRpdmUgPSAxO1xuICAgICAgcmV0dXJuIHIuX25vcm1TaWduKCk7XG4gICAgfVxuXG4gICAgLy8gYS5sZW5ndGggPiBiLmxlbmd0aFxuICAgIHZhciBhLCBiO1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHtcbiAgICAgIGEgPSB0aGlzO1xuICAgICAgYiA9IG51bTtcbiAgICB9IGVsc2Uge1xuICAgICAgYSA9IG51bTtcbiAgICAgIGIgPSB0aGlzO1xuICAgIH1cblxuICAgIHZhciBjYXJyeSA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBiLmxlbmd0aDsgaSsrKSB7XG4gICAgICByID0gKGEud29yZHNbaV0gfCAwKSArIChiLndvcmRzW2ldIHwgMCkgKyBjYXJyeTtcbiAgICAgIHRoaXMud29yZHNbaV0gPSByICYgMHgzZmZmZmZmO1xuICAgICAgY2FycnkgPSByID4+PiAyNjtcbiAgICB9XG4gICAgZm9yICg7IGNhcnJ5ICE9PSAwICYmIGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICByID0gKGEud29yZHNbaV0gfCAwKSArIGNhcnJ5O1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IHIgJiAweDNmZmZmZmY7XG4gICAgICBjYXJyeSA9IHIgPj4+IDI2O1xuICAgIH1cblxuICAgIHRoaXMubGVuZ3RoID0gYS5sZW5ndGg7XG4gICAgaWYgKGNhcnJ5ICE9PSAwKSB7XG4gICAgICB0aGlzLndvcmRzW3RoaXMubGVuZ3RoXSA9IGNhcnJ5O1xuICAgICAgdGhpcy5sZW5ndGgrKztcbiAgICAvLyBDb3B5IHRoZSByZXN0IG9mIHRoZSB3b3Jkc1xuICAgIH0gZWxzZSBpZiAoYSAhPT0gdGhpcykge1xuICAgICAgZm9yICg7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMud29yZHNbaV0gPSBhLndvcmRzW2ldO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8vIEFkZCBgbnVtYCB0byBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZCAobnVtKSB7XG4gICAgdmFyIHJlcztcbiAgICBpZiAobnVtLm5lZ2F0aXZlICE9PSAwICYmIHRoaXMubmVnYXRpdmUgPT09IDApIHtcbiAgICAgIG51bS5uZWdhdGl2ZSA9IDA7XG4gICAgICByZXMgPSB0aGlzLnN1YihudW0pO1xuICAgICAgbnVtLm5lZ2F0aXZlIF49IDE7XG4gICAgICByZXR1cm4gcmVzO1xuICAgIH0gZWxzZSBpZiAobnVtLm5lZ2F0aXZlID09PSAwICYmIHRoaXMubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgICAgcmVzID0gbnVtLnN1Yih0aGlzKTtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAxO1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBpZiAodGhpcy5sZW5ndGggPiBudW0ubGVuZ3RoKSByZXR1cm4gdGhpcy5jbG9uZSgpLmlhZGQobnVtKTtcblxuICAgIHJldHVybiBudW0uY2xvbmUoKS5pYWRkKHRoaXMpO1xuICB9O1xuXG4gIC8vIFN1YnRyYWN0IGBudW1gIGZyb20gYHRoaXNgIGluLXBsYWNlXG4gIEJOLnByb3RvdHlwZS5pc3ViID0gZnVuY3Rpb24gaXN1YiAobnVtKSB7XG4gICAgLy8gdGhpcyAtICgtbnVtKSA9IHRoaXMgKyBudW1cbiAgICBpZiAobnVtLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICBudW0ubmVnYXRpdmUgPSAwO1xuICAgICAgdmFyIHIgPSB0aGlzLmlhZGQobnVtKTtcbiAgICAgIG51bS5uZWdhdGl2ZSA9IDE7XG4gICAgICByZXR1cm4gci5fbm9ybVNpZ24oKTtcblxuICAgIC8vIC10aGlzIC0gbnVtID0gLSh0aGlzICsgbnVtKVxuICAgIH0gZWxzZSBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDA7XG4gICAgICB0aGlzLmlhZGQobnVtKTtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAxO1xuICAgICAgcmV0dXJuIHRoaXMuX25vcm1TaWduKCk7XG4gICAgfVxuXG4gICAgLy8gQXQgdGhpcyBwb2ludCBib3RoIG51bWJlcnMgYXJlIHBvc2l0aXZlXG4gICAgdmFyIGNtcCA9IHRoaXMuY21wKG51bSk7XG5cbiAgICAvLyBPcHRpbWl6YXRpb24gLSB6ZXJvaWZ5XG4gICAgaWYgKGNtcCA9PT0gMCkge1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDA7XG4gICAgICB0aGlzLmxlbmd0aCA9IDE7XG4gICAgICB0aGlzLndvcmRzWzBdID0gMDtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIGEgPiBiXG4gICAgdmFyIGEsIGI7XG4gICAgaWYgKGNtcCA+IDApIHtcbiAgICAgIGEgPSB0aGlzO1xuICAgICAgYiA9IG51bTtcbiAgICB9IGVsc2Uge1xuICAgICAgYSA9IG51bTtcbiAgICAgIGIgPSB0aGlzO1xuICAgIH1cblxuICAgIHZhciBjYXJyeSA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBiLmxlbmd0aDsgaSsrKSB7XG4gICAgICByID0gKGEud29yZHNbaV0gfCAwKSAtIChiLndvcmRzW2ldIHwgMCkgKyBjYXJyeTtcbiAgICAgIGNhcnJ5ID0gciA+PiAyNjtcbiAgICAgIHRoaXMud29yZHNbaV0gPSByICYgMHgzZmZmZmZmO1xuICAgIH1cbiAgICBmb3IgKDsgY2FycnkgIT09IDAgJiYgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIHIgPSAoYS53b3Jkc1tpXSB8IDApICsgY2Fycnk7XG4gICAgICBjYXJyeSA9IHIgPj4gMjY7XG4gICAgICB0aGlzLndvcmRzW2ldID0gciAmIDB4M2ZmZmZmZjtcbiAgICB9XG5cbiAgICAvLyBDb3B5IHJlc3Qgb2YgdGhlIHdvcmRzXG4gICAgaWYgKGNhcnJ5ID09PSAwICYmIGkgPCBhLmxlbmd0aCAmJiBhICE9PSB0aGlzKSB7XG4gICAgICBmb3IgKDsgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpcy53b3Jkc1tpXSA9IGEud29yZHNbaV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5sZW5ndGggPSBNYXRoLm1heCh0aGlzLmxlbmd0aCwgaSk7XG5cbiAgICBpZiAoYSAhPT0gdGhpcykge1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDE7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICAvLyBTdWJ0cmFjdCBgbnVtYCBmcm9tIGB0aGlzYFxuICBCTi5wcm90b3R5cGUuc3ViID0gZnVuY3Rpb24gc3ViIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmlzdWIobnVtKTtcbiAgfTtcblxuICBmdW5jdGlvbiBzbWFsbE11bFRvIChzZWxmLCBudW0sIG91dCkge1xuICAgIG91dC5uZWdhdGl2ZSA9IG51bS5uZWdhdGl2ZSBeIHNlbGYubmVnYXRpdmU7XG4gICAgdmFyIGxlbiA9IChzZWxmLmxlbmd0aCArIG51bS5sZW5ndGgpIHwgMDtcbiAgICBvdXQubGVuZ3RoID0gbGVuO1xuICAgIGxlbiA9IChsZW4gLSAxKSB8IDA7XG5cbiAgICAvLyBQZWVsIG9uZSBpdGVyYXRpb24gKGNvbXBpbGVyIGNhbid0IGRvIGl0LCBiZWNhdXNlIG9mIGNvZGUgY29tcGxleGl0eSlcbiAgICB2YXIgYSA9IHNlbGYud29yZHNbMF0gfCAwO1xuICAgIHZhciBiID0gbnVtLndvcmRzWzBdIHwgMDtcbiAgICB2YXIgciA9IGEgKiBiO1xuXG4gICAgdmFyIGxvID0gciAmIDB4M2ZmZmZmZjtcbiAgICB2YXIgY2FycnkgPSAociAvIDB4NDAwMDAwMCkgfCAwO1xuICAgIG91dC53b3Jkc1swXSA9IGxvO1xuXG4gICAgZm9yICh2YXIgayA9IDE7IGsgPCBsZW47IGsrKykge1xuICAgICAgLy8gU3VtIGFsbCB3b3JkcyB3aXRoIHRoZSBzYW1lIGBpICsgaiA9IGtgIGFuZCBhY2N1bXVsYXRlIGBuY2FycnlgLFxuICAgICAgLy8gbm90ZSB0aGF0IG5jYXJyeSBjb3VsZCBiZSA+PSAweDNmZmZmZmZcbiAgICAgIHZhciBuY2FycnkgPSBjYXJyeSA+Pj4gMjY7XG4gICAgICB2YXIgcndvcmQgPSBjYXJyeSAmIDB4M2ZmZmZmZjtcbiAgICAgIHZhciBtYXhKID0gTWF0aC5taW4oaywgbnVtLmxlbmd0aCAtIDEpO1xuICAgICAgZm9yICh2YXIgaiA9IE1hdGgubWF4KDAsIGsgLSBzZWxmLmxlbmd0aCArIDEpOyBqIDw9IG1heEo7IGorKykge1xuICAgICAgICB2YXIgaSA9IChrIC0gaikgfCAwO1xuICAgICAgICBhID0gc2VsZi53b3Jkc1tpXSB8IDA7XG4gICAgICAgIGIgPSBudW0ud29yZHNbal0gfCAwO1xuICAgICAgICByID0gYSAqIGIgKyByd29yZDtcbiAgICAgICAgbmNhcnJ5ICs9IChyIC8gMHg0MDAwMDAwKSB8IDA7XG4gICAgICAgIHJ3b3JkID0gciAmIDB4M2ZmZmZmZjtcbiAgICAgIH1cbiAgICAgIG91dC53b3Jkc1trXSA9IHJ3b3JkIHwgMDtcbiAgICAgIGNhcnJ5ID0gbmNhcnJ5IHwgMDtcbiAgICB9XG4gICAgaWYgKGNhcnJ5ICE9PSAwKSB7XG4gICAgICBvdXQud29yZHNba10gPSBjYXJyeSB8IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dC5sZW5ndGgtLTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0LnN0cmlwKCk7XG4gIH1cblxuICAvLyBUT0RPKGluZHV0bnkpOiBpdCBtYXkgYmUgcmVhc29uYWJsZSB0byBvbWl0IGl0IGZvciB1c2VycyB3aG8gZG9uJ3QgbmVlZFxuICAvLyB0byB3b3JrIHdpdGggMjU2LWJpdCBudW1iZXJzLCBvdGhlcndpc2UgaXQgZ2l2ZXMgMjAlIGltcHJvdmVtZW50IGZvciAyNTYtYml0XG4gIC8vIG11bHRpcGxpY2F0aW9uIChsaWtlIGVsbGlwdGljIHNlY3AyNTZrMSkuXG4gIHZhciBjb21iMTBNdWxUbyA9IGZ1bmN0aW9uIGNvbWIxME11bFRvIChzZWxmLCBudW0sIG91dCkge1xuICAgIHZhciBhID0gc2VsZi53b3JkcztcbiAgICB2YXIgYiA9IG51bS53b3JkcztcbiAgICB2YXIgbyA9IG91dC53b3JkcztcbiAgICB2YXIgYyA9IDA7XG4gICAgdmFyIGxvO1xuICAgIHZhciBtaWQ7XG4gICAgdmFyIGhpO1xuICAgIHZhciBhMCA9IGFbMF0gfCAwO1xuICAgIHZhciBhbDAgPSBhMCAmIDB4MWZmZjtcbiAgICB2YXIgYWgwID0gYTAgPj4+IDEzO1xuICAgIHZhciBhMSA9IGFbMV0gfCAwO1xuICAgIHZhciBhbDEgPSBhMSAmIDB4MWZmZjtcbiAgICB2YXIgYWgxID0gYTEgPj4+IDEzO1xuICAgIHZhciBhMiA9IGFbMl0gfCAwO1xuICAgIHZhciBhbDIgPSBhMiAmIDB4MWZmZjtcbiAgICB2YXIgYWgyID0gYTIgPj4+IDEzO1xuICAgIHZhciBhMyA9IGFbM10gfCAwO1xuICAgIHZhciBhbDMgPSBhMyAmIDB4MWZmZjtcbiAgICB2YXIgYWgzID0gYTMgPj4+IDEzO1xuICAgIHZhciBhNCA9IGFbNF0gfCAwO1xuICAgIHZhciBhbDQgPSBhNCAmIDB4MWZmZjtcbiAgICB2YXIgYWg0ID0gYTQgPj4+IDEzO1xuICAgIHZhciBhNSA9IGFbNV0gfCAwO1xuICAgIHZhciBhbDUgPSBhNSAmIDB4MWZmZjtcbiAgICB2YXIgYWg1ID0gYTUgPj4+IDEzO1xuICAgIHZhciBhNiA9IGFbNl0gfCAwO1xuICAgIHZhciBhbDYgPSBhNiAmIDB4MWZmZjtcbiAgICB2YXIgYWg2ID0gYTYgPj4+IDEzO1xuICAgIHZhciBhNyA9IGFbN10gfCAwO1xuICAgIHZhciBhbDcgPSBhNyAmIDB4MWZmZjtcbiAgICB2YXIgYWg3ID0gYTcgPj4+IDEzO1xuICAgIHZhciBhOCA9IGFbOF0gfCAwO1xuICAgIHZhciBhbDggPSBhOCAmIDB4MWZmZjtcbiAgICB2YXIgYWg4ID0gYTggPj4+IDEzO1xuICAgIHZhciBhOSA9IGFbOV0gfCAwO1xuICAgIHZhciBhbDkgPSBhOSAmIDB4MWZmZjtcbiAgICB2YXIgYWg5ID0gYTkgPj4+IDEzO1xuICAgIHZhciBiMCA9IGJbMF0gfCAwO1xuICAgIHZhciBibDAgPSBiMCAmIDB4MWZmZjtcbiAgICB2YXIgYmgwID0gYjAgPj4+IDEzO1xuICAgIHZhciBiMSA9IGJbMV0gfCAwO1xuICAgIHZhciBibDEgPSBiMSAmIDB4MWZmZjtcbiAgICB2YXIgYmgxID0gYjEgPj4+IDEzO1xuICAgIHZhciBiMiA9IGJbMl0gfCAwO1xuICAgIHZhciBibDIgPSBiMiAmIDB4MWZmZjtcbiAgICB2YXIgYmgyID0gYjIgPj4+IDEzO1xuICAgIHZhciBiMyA9IGJbM10gfCAwO1xuICAgIHZhciBibDMgPSBiMyAmIDB4MWZmZjtcbiAgICB2YXIgYmgzID0gYjMgPj4+IDEzO1xuICAgIHZhciBiNCA9IGJbNF0gfCAwO1xuICAgIHZhciBibDQgPSBiNCAmIDB4MWZmZjtcbiAgICB2YXIgYmg0ID0gYjQgPj4+IDEzO1xuICAgIHZhciBiNSA9IGJbNV0gfCAwO1xuICAgIHZhciBibDUgPSBiNSAmIDB4MWZmZjtcbiAgICB2YXIgYmg1ID0gYjUgPj4+IDEzO1xuICAgIHZhciBiNiA9IGJbNl0gfCAwO1xuICAgIHZhciBibDYgPSBiNiAmIDB4MWZmZjtcbiAgICB2YXIgYmg2ID0gYjYgPj4+IDEzO1xuICAgIHZhciBiNyA9IGJbN10gfCAwO1xuICAgIHZhciBibDcgPSBiNyAmIDB4MWZmZjtcbiAgICB2YXIgYmg3ID0gYjcgPj4+IDEzO1xuICAgIHZhciBiOCA9IGJbOF0gfCAwO1xuICAgIHZhciBibDggPSBiOCAmIDB4MWZmZjtcbiAgICB2YXIgYmg4ID0gYjggPj4+IDEzO1xuICAgIHZhciBiOSA9IGJbOV0gfCAwO1xuICAgIHZhciBibDkgPSBiOSAmIDB4MWZmZjtcbiAgICB2YXIgYmg5ID0gYjkgPj4+IDEzO1xuXG4gICAgb3V0Lm5lZ2F0aXZlID0gc2VsZi5uZWdhdGl2ZSBeIG51bS5uZWdhdGl2ZTtcbiAgICBvdXQubGVuZ3RoID0gMTk7XG4gICAgLyogayA9IDAgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDAsIGJsMCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsMCwgYmgwKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMCwgYmwwKTtcbiAgICBoaSA9IE1hdGguaW11bChhaDAsIGJoMCk7XG4gICAgdmFyIHcwID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzAgPj4+IDI2KTtcbiAgICB3MCAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDEgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDEsIGJsMCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsMSwgYmgwKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMSwgYmwwKTtcbiAgICBoaSA9IE1hdGguaW11bChhaDEsIGJoMCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMCwgYmwxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMCwgYmgxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMCwgYmwxKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgwLCBiaDEpO1xuICAgIHZhciB3MSA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcxID4+PiAyNik7XG4gICAgdzEgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAyICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWwyLCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDIsIGJoMCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDIsIGJsMCk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWgyLCBiaDApO1xuICAgIGxvICs9IE1hdGguaW11bChhbDEsIGJsMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDEsIGJoMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDEsIGJsMSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMSwgYmgxKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwwLCBibDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwwLCBiaDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgwLCBibDIpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDAsIGJoMik7XG4gICAgdmFyIHcyID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzIgPj4+IDI2KTtcbiAgICB3MiAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDMgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDMsIGJsMCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsMywgYmgwKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMywgYmwwKTtcbiAgICBoaSA9IE1hdGguaW11bChhaDMsIGJoMCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMiwgYmwxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMiwgYmgxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMiwgYmwxKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgyLCBiaDEpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDEsIGJsMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDEsIGJoMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDEsIGJsMik7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMSwgYmgyKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwwLCBibDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwwLCBiaDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgwLCBibDMpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDAsIGJoMyk7XG4gICAgdmFyIHczID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzMgPj4+IDI2KTtcbiAgICB3MyAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDQgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDQsIGJsMCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsNCwgYmgwKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNCwgYmwwKTtcbiAgICBoaSA9IE1hdGguaW11bChhaDQsIGJoMCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMywgYmwxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMywgYmgxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMywgYmwxKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgzLCBiaDEpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDIsIGJsMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDIsIGJoMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDIsIGJsMik7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMiwgYmgyKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwxLCBibDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwxLCBiaDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgxLCBibDMpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDEsIGJoMyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMCwgYmw0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMCwgYmg0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMCwgYmw0KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgwLCBiaDQpO1xuICAgIHZhciB3NCA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHc0ID4+PiAyNik7XG4gICAgdzQgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSA1ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw1LCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDUsIGJoMCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDUsIGJsMCk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg1LCBiaDApO1xuICAgIGxvICs9IE1hdGguaW11bChhbDQsIGJsMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDQsIGJoMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDQsIGJsMSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNCwgYmgxKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwzLCBibDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwzLCBiaDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgzLCBibDIpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDMsIGJoMik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMiwgYmwzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMiwgYmgzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMiwgYmwzKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgyLCBiaDMpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDEsIGJsNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDEsIGJoNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDEsIGJsNCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMSwgYmg0KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwwLCBibDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwwLCBiaDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgwLCBibDUpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDAsIGJoNSk7XG4gICAgdmFyIHc1ID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzUgPj4+IDI2KTtcbiAgICB3NSAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDYgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDYsIGJsMCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsNiwgYmgwKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNiwgYmwwKTtcbiAgICBoaSA9IE1hdGguaW11bChhaDYsIGJoMCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNSwgYmwxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNSwgYmgxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNSwgYmwxKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg1LCBiaDEpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDQsIGJsMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDQsIGJoMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDQsIGJsMik7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNCwgYmgyKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwzLCBibDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwzLCBiaDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgzLCBibDMpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDMsIGJoMyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMiwgYmw0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMiwgYmg0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMiwgYmw0KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgyLCBiaDQpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDEsIGJsNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDEsIGJoNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDEsIGJsNSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMSwgYmg1KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwwLCBibDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwwLCBiaDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgwLCBibDYpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDAsIGJoNik7XG4gICAgdmFyIHc2ID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzYgPj4+IDI2KTtcbiAgICB3NiAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDcgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDcsIGJsMCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsNywgYmgwKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNywgYmwwKTtcbiAgICBoaSA9IE1hdGguaW11bChhaDcsIGJoMCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNiwgYmwxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNiwgYmgxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNiwgYmwxKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg2LCBiaDEpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDUsIGJsMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDUsIGJoMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDUsIGJsMik7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNSwgYmgyKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw0LCBibDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw0LCBiaDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg0LCBibDMpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDQsIGJoMyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMywgYmw0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMywgYmg0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMywgYmw0KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgzLCBiaDQpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDIsIGJsNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDIsIGJoNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDIsIGJsNSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMiwgYmg1KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwxLCBibDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwxLCBiaDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgxLCBibDYpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDEsIGJoNik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMCwgYmw3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMCwgYmg3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMCwgYmw3KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgwLCBiaDcpO1xuICAgIHZhciB3NyA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHc3ID4+PiAyNik7XG4gICAgdzcgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSA4ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw4LCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDgsIGJoMCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDgsIGJsMCk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg4LCBiaDApO1xuICAgIGxvICs9IE1hdGguaW11bChhbDcsIGJsMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDcsIGJoMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDcsIGJsMSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNywgYmgxKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw2LCBibDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw2LCBiaDIpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg2LCBibDIpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDYsIGJoMik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNSwgYmwzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNSwgYmgzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNSwgYmwzKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg1LCBiaDMpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDQsIGJsNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDQsIGJoNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDQsIGJsNCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNCwgYmg0KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwzLCBibDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwzLCBiaDUpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgzLCBibDUpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDMsIGJoNSk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMiwgYmw2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMiwgYmg2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMiwgYmw2KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgyLCBiaDYpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDEsIGJsNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDEsIGJoNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDEsIGJsNyk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMSwgYmg3KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwwLCBibDgpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwwLCBiaDgpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgwLCBibDgpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDAsIGJoOCk7XG4gICAgdmFyIHc4ID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzggPj4+IDI2KTtcbiAgICB3OCAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDkgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDksIGJsMCk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsOSwgYmgwKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoOSwgYmwwKTtcbiAgICBoaSA9IE1hdGguaW11bChhaDksIGJoMCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsOCwgYmwxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsOCwgYmgxKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoOCwgYmwxKTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg4LCBiaDEpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDcsIGJsMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDcsIGJoMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDcsIGJsMik7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNywgYmgyKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw2LCBibDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw2LCBiaDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg2LCBibDMpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDYsIGJoMyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNSwgYmw0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNSwgYmg0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNSwgYmw0KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg1LCBiaDQpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDQsIGJsNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDQsIGJoNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDQsIGJsNSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNCwgYmg1KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwzLCBibDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwzLCBiaDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgzLCBibDYpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDMsIGJoNik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMiwgYmw3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMiwgYmg3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMiwgYmw3KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgyLCBiaDcpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDEsIGJsOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDEsIGJoOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDEsIGJsOCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMSwgYmg4KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwwLCBibDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwwLCBiaDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgwLCBibDkpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDAsIGJoOSk7XG4gICAgdmFyIHc5ID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzkgPj4+IDI2KTtcbiAgICB3OSAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDEwICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDEpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoMSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDksIGJsMSk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDEpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDgsIGJsMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDgsIGJoMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDgsIGJsMik7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoOCwgYmgyKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw3LCBibDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw3LCBiaDMpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg3LCBibDMpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDcsIGJoMyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNiwgYmw0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNiwgYmg0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNiwgYmw0KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg2LCBiaDQpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDUsIGJsNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDUsIGJoNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDUsIGJsNSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNSwgYmg1KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw0LCBibDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw0LCBiaDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg0LCBibDYpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDQsIGJoNik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMywgYmw3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMywgYmg3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMywgYmw3KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgzLCBiaDcpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDIsIGJsOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDIsIGJoOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDIsIGJsOCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMiwgYmg4KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwxLCBibDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwxLCBiaDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgxLCBibDkpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDEsIGJoOSk7XG4gICAgdmFyIHcxMCA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcxMCA+Pj4gMjYpO1xuICAgIHcxMCAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDExICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDIpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoMik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDksIGJsMik7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDIpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDgsIGJsMyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDgsIGJoMyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDgsIGJsMyk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoOCwgYmgzKTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw3LCBibDQpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw3LCBiaDQpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg3LCBibDQpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDcsIGJoNCk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNiwgYmw1KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNiwgYmg1KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNiwgYmw1KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg2LCBiaDUpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDUsIGJsNik7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDUsIGJoNik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDUsIGJsNik7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNSwgYmg2KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw0LCBibDcpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw0LCBiaDcpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg0LCBibDcpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDQsIGJoNyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsMywgYmw4KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsMywgYmg4KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoMywgYmw4KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWgzLCBiaDgpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDIsIGJsOSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDIsIGJoOSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDIsIGJsOSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoMiwgYmg5KTtcbiAgICB2YXIgdzExID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzExID4+PiAyNik7XG4gICAgdzExICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gMTIgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDksIGJsMyk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsOSwgYmgzKTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoOSwgYmwzKTtcbiAgICBoaSA9IE1hdGguaW11bChhaDksIGJoMyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsOCwgYmw0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsOCwgYmg0KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoOCwgYmw0KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg4LCBiaDQpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDcsIGJsNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDcsIGJoNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDcsIGJsNSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNywgYmg1KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw2LCBibDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw2LCBiaDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg2LCBibDYpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDYsIGJoNik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNSwgYmw3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNSwgYmg3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNSwgYmw3KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg1LCBiaDcpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDQsIGJsOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDQsIGJoOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDQsIGJsOCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNCwgYmg4KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWwzLCBibDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWwzLCBiaDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWgzLCBibDkpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDMsIGJoOSk7XG4gICAgdmFyIHcxMiA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcxMiA+Pj4gMjYpO1xuICAgIHcxMiAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDEzICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDQpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoNCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDksIGJsNCk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDQpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDgsIGJsNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDgsIGJoNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDgsIGJsNSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoOCwgYmg1KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw3LCBibDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw3LCBiaDYpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg3LCBibDYpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDcsIGJoNik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNiwgYmw3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNiwgYmg3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNiwgYmw3KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg2LCBiaDcpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDUsIGJsOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDUsIGJoOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDUsIGJsOCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNSwgYmg4KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw0LCBibDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw0LCBiaDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg0LCBibDkpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDQsIGJoOSk7XG4gICAgdmFyIHcxMyA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcxMyA+Pj4gMjYpO1xuICAgIHcxMyAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDE0ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDUpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoNSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDksIGJsNSk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDUpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDgsIGJsNik7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDgsIGJoNik7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDgsIGJsNik7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoOCwgYmg2KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw3LCBibDcpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw3LCBiaDcpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg3LCBibDcpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDcsIGJoNyk7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsNiwgYmw4KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsNiwgYmg4KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoNiwgYmw4KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg2LCBiaDgpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDUsIGJsOSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDUsIGJoOSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDUsIGJsOSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNSwgYmg5KTtcbiAgICB2YXIgdzE0ID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzE0ID4+PiAyNik7XG4gICAgdzE0ICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gMTUgKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDksIGJsNik7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsOSwgYmg2KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoOSwgYmw2KTtcbiAgICBoaSA9IE1hdGguaW11bChhaDksIGJoNik7XG4gICAgbG8gKz0gTWF0aC5pbXVsKGFsOCwgYmw3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFsOCwgYmg3KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoOCwgYmw3KTtcbiAgICBoaSArPSBNYXRoLmltdWwoYWg4LCBiaDcpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDcsIGJsOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDcsIGJoOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDcsIGJsOCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoNywgYmg4KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw2LCBibDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw2LCBiaDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg2LCBibDkpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDYsIGJoOSk7XG4gICAgdmFyIHcxNSA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcxNSA+Pj4gMjYpO1xuICAgIHcxNSAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDE2ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDcpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoNyk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDksIGJsNyk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDcpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDgsIGJsOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDgsIGJoOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDgsIGJsOCk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoOCwgYmg4KTtcbiAgICBsbyArPSBNYXRoLmltdWwoYWw3LCBibDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWw3LCBiaDkpO1xuICAgIG1pZCArPSBNYXRoLmltdWwoYWg3LCBibDkpO1xuICAgIGhpICs9IE1hdGguaW11bChhaDcsIGJoOSk7XG4gICAgdmFyIHcxNiA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcxNiA+Pj4gMjYpO1xuICAgIHcxNiAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDE3ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDgpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoOCk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDksIGJsOCk7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDgpO1xuICAgIGxvICs9IE1hdGguaW11bChhbDgsIGJsOSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhbDgsIGJoOSk7XG4gICAgbWlkICs9IE1hdGguaW11bChhaDgsIGJsOSk7XG4gICAgaGkgKz0gTWF0aC5pbXVsKGFoOCwgYmg5KTtcbiAgICB2YXIgdzE3ID0gYyArIGxvICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKTtcbiAgICBjID0gaGkgKyAobWlkID4+PiAxMykgKyAodzE3ID4+PiAyNik7XG4gICAgdzE3ICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gMTggKi9cbiAgICBsbyA9IE1hdGguaW11bChhbDksIGJsOSk7XG4gICAgbWlkID0gTWF0aC5pbXVsKGFsOSwgYmg5KTtcbiAgICBtaWQgKz0gTWF0aC5pbXVsKGFoOSwgYmw5KTtcbiAgICBoaSA9IE1hdGguaW11bChhaDksIGJoOSk7XG4gICAgdmFyIHcxOCA9IGMgKyBsbyArICgobWlkICYgMHgxZmZmKSA8PCAxMyk7XG4gICAgYyA9IGhpICsgKG1pZCA+Pj4gMTMpICsgKHcxOCA+Pj4gMjYpO1xuICAgIHcxOCAmPSAweDNmZmZmZmY7XG4gICAgb1swXSA9IHcwO1xuICAgIG9bMV0gPSB3MTtcbiAgICBvWzJdID0gdzI7XG4gICAgb1szXSA9IHczO1xuICAgIG9bNF0gPSB3NDtcbiAgICBvWzVdID0gdzU7XG4gICAgb1s2XSA9IHc2O1xuICAgIG9bN10gPSB3NztcbiAgICBvWzhdID0gdzg7XG4gICAgb1s5XSA9IHc5O1xuICAgIG9bMTBdID0gdzEwO1xuICAgIG9bMTFdID0gdzExO1xuICAgIG9bMTJdID0gdzEyO1xuICAgIG9bMTNdID0gdzEzO1xuICAgIG9bMTRdID0gdzE0O1xuICAgIG9bMTVdID0gdzE1O1xuICAgIG9bMTZdID0gdzE2O1xuICAgIG9bMTddID0gdzE3O1xuICAgIG9bMThdID0gdzE4O1xuICAgIGlmIChjICE9PSAwKSB7XG4gICAgICBvWzE5XSA9IGM7XG4gICAgICBvdXQubGVuZ3RoKys7XG4gICAgfVxuICAgIHJldHVybiBvdXQ7XG4gIH07XG5cbiAgLy8gUG9seWZpbGwgY29tYlxuICBpZiAoIU1hdGguaW11bCkge1xuICAgIGNvbWIxME11bFRvID0gc21hbGxNdWxUbztcbiAgfVxuXG4gIGZ1bmN0aW9uIGJpZ011bFRvIChzZWxmLCBudW0sIG91dCkge1xuICAgIG91dC5uZWdhdGl2ZSA9IG51bS5uZWdhdGl2ZSBeIHNlbGYubmVnYXRpdmU7XG4gICAgb3V0Lmxlbmd0aCA9IHNlbGYubGVuZ3RoICsgbnVtLmxlbmd0aDtcblxuICAgIHZhciBjYXJyeSA9IDA7XG4gICAgdmFyIGhuY2FycnkgPSAwO1xuICAgIGZvciAodmFyIGsgPSAwOyBrIDwgb3V0Lmxlbmd0aCAtIDE7IGsrKykge1xuICAgICAgLy8gU3VtIGFsbCB3b3JkcyB3aXRoIHRoZSBzYW1lIGBpICsgaiA9IGtgIGFuZCBhY2N1bXVsYXRlIGBuY2FycnlgLFxuICAgICAgLy8gbm90ZSB0aGF0IG5jYXJyeSBjb3VsZCBiZSA+PSAweDNmZmZmZmZcbiAgICAgIHZhciBuY2FycnkgPSBobmNhcnJ5O1xuICAgICAgaG5jYXJyeSA9IDA7XG4gICAgICB2YXIgcndvcmQgPSBjYXJyeSAmIDB4M2ZmZmZmZjtcbiAgICAgIHZhciBtYXhKID0gTWF0aC5taW4oaywgbnVtLmxlbmd0aCAtIDEpO1xuICAgICAgZm9yICh2YXIgaiA9IE1hdGgubWF4KDAsIGsgLSBzZWxmLmxlbmd0aCArIDEpOyBqIDw9IG1heEo7IGorKykge1xuICAgICAgICB2YXIgaSA9IGsgLSBqO1xuICAgICAgICB2YXIgYSA9IHNlbGYud29yZHNbaV0gfCAwO1xuICAgICAgICB2YXIgYiA9IG51bS53b3Jkc1tqXSB8IDA7XG4gICAgICAgIHZhciByID0gYSAqIGI7XG5cbiAgICAgICAgdmFyIGxvID0gciAmIDB4M2ZmZmZmZjtcbiAgICAgICAgbmNhcnJ5ID0gKG5jYXJyeSArICgociAvIDB4NDAwMDAwMCkgfCAwKSkgfCAwO1xuICAgICAgICBsbyA9IChsbyArIHJ3b3JkKSB8IDA7XG4gICAgICAgIHJ3b3JkID0gbG8gJiAweDNmZmZmZmY7XG4gICAgICAgIG5jYXJyeSA9IChuY2FycnkgKyAobG8gPj4+IDI2KSkgfCAwO1xuXG4gICAgICAgIGhuY2FycnkgKz0gbmNhcnJ5ID4+PiAyNjtcbiAgICAgICAgbmNhcnJ5ICY9IDB4M2ZmZmZmZjtcbiAgICAgIH1cbiAgICAgIG91dC53b3Jkc1trXSA9IHJ3b3JkO1xuICAgICAgY2FycnkgPSBuY2Fycnk7XG4gICAgICBuY2FycnkgPSBobmNhcnJ5O1xuICAgIH1cbiAgICBpZiAoY2FycnkgIT09IDApIHtcbiAgICAgIG91dC53b3Jkc1trXSA9IGNhcnJ5O1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXQubGVuZ3RoLS07XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dC5zdHJpcCgpO1xuICB9XG5cbiAgZnVuY3Rpb24ganVtYm9NdWxUbyAoc2VsZiwgbnVtLCBvdXQpIHtcbiAgICB2YXIgZmZ0bSA9IG5ldyBGRlRNKCk7XG4gICAgcmV0dXJuIGZmdG0ubXVscChzZWxmLCBudW0sIG91dCk7XG4gIH1cblxuICBCTi5wcm90b3R5cGUubXVsVG8gPSBmdW5jdGlvbiBtdWxUbyAobnVtLCBvdXQpIHtcbiAgICB2YXIgcmVzO1xuICAgIHZhciBsZW4gPSB0aGlzLmxlbmd0aCArIG51bS5sZW5ndGg7XG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAxMCAmJiBudW0ubGVuZ3RoID09PSAxMCkge1xuICAgICAgcmVzID0gY29tYjEwTXVsVG8odGhpcywgbnVtLCBvdXQpO1xuICAgIH0gZWxzZSBpZiAobGVuIDwgNjMpIHtcbiAgICAgIHJlcyA9IHNtYWxsTXVsVG8odGhpcywgbnVtLCBvdXQpO1xuICAgIH0gZWxzZSBpZiAobGVuIDwgMTAyNCkge1xuICAgICAgcmVzID0gYmlnTXVsVG8odGhpcywgbnVtLCBvdXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXMgPSBqdW1ib011bFRvKHRoaXMsIG51bSwgb3V0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIC8vIENvb2xleS1UdWtleSBhbGdvcml0aG0gZm9yIEZGVFxuICAvLyBzbGlnaHRseSByZXZpc2l0ZWQgdG8gcmVseSBvbiBsb29waW5nIGluc3RlYWQgb2YgcmVjdXJzaW9uXG5cbiAgZnVuY3Rpb24gRkZUTSAoeCwgeSkge1xuICAgIHRoaXMueCA9IHg7XG4gICAgdGhpcy55ID0geTtcbiAgfVxuXG4gIEZGVE0ucHJvdG90eXBlLm1ha2VSQlQgPSBmdW5jdGlvbiBtYWtlUkJUIChOKSB7XG4gICAgdmFyIHQgPSBuZXcgQXJyYXkoTik7XG4gICAgdmFyIGwgPSBCTi5wcm90b3R5cGUuX2NvdW50Qml0cyhOKSAtIDE7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBOOyBpKyspIHtcbiAgICAgIHRbaV0gPSB0aGlzLnJldkJpbihpLCBsLCBOKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdDtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGJpbmFyeS1yZXZlcnNlZCByZXByZXNlbnRhdGlvbiBvZiBgeGBcbiAgRkZUTS5wcm90b3R5cGUucmV2QmluID0gZnVuY3Rpb24gcmV2QmluICh4LCBsLCBOKSB7XG4gICAgaWYgKHggPT09IDAgfHwgeCA9PT0gTiAtIDEpIHJldHVybiB4O1xuXG4gICAgdmFyIHJiID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGw7IGkrKykge1xuICAgICAgcmIgfD0gKHggJiAxKSA8PCAobCAtIGkgLSAxKTtcbiAgICAgIHggPj49IDE7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJiO1xuICB9O1xuXG4gIC8vIFBlcmZvcm1zIFwidHdlZWRsaW5nXCIgcGhhc2UsIHRoZXJlZm9yZSAnZW11bGF0aW5nJ1xuICAvLyBiZWhhdmlvdXIgb2YgdGhlIHJlY3Vyc2l2ZSBhbGdvcml0aG1cbiAgRkZUTS5wcm90b3R5cGUucGVybXV0ZSA9IGZ1bmN0aW9uIHBlcm11dGUgKHJidCwgcndzLCBpd3MsIHJ0d3MsIGl0d3MsIE4pIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IE47IGkrKykge1xuICAgICAgcnR3c1tpXSA9IHJ3c1tyYnRbaV1dO1xuICAgICAgaXR3c1tpXSA9IGl3c1tyYnRbaV1dO1xuICAgIH1cbiAgfTtcblxuICBGRlRNLnByb3RvdHlwZS50cmFuc2Zvcm0gPSBmdW5jdGlvbiB0cmFuc2Zvcm0gKHJ3cywgaXdzLCBydHdzLCBpdHdzLCBOLCByYnQpIHtcbiAgICB0aGlzLnBlcm11dGUocmJ0LCByd3MsIGl3cywgcnR3cywgaXR3cywgTik7XG5cbiAgICBmb3IgKHZhciBzID0gMTsgcyA8IE47IHMgPDw9IDEpIHtcbiAgICAgIHZhciBsID0gcyA8PCAxO1xuXG4gICAgICB2YXIgcnR3ZGYgPSBNYXRoLmNvcygyICogTWF0aC5QSSAvIGwpO1xuICAgICAgdmFyIGl0d2RmID0gTWF0aC5zaW4oMiAqIE1hdGguUEkgLyBsKTtcblxuICAgICAgZm9yICh2YXIgcCA9IDA7IHAgPCBOOyBwICs9IGwpIHtcbiAgICAgICAgdmFyIHJ0d2RmXyA9IHJ0d2RmO1xuICAgICAgICB2YXIgaXR3ZGZfID0gaXR3ZGY7XG5cbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBzOyBqKyspIHtcbiAgICAgICAgICB2YXIgcmUgPSBydHdzW3AgKyBqXTtcbiAgICAgICAgICB2YXIgaWUgPSBpdHdzW3AgKyBqXTtcblxuICAgICAgICAgIHZhciBybyA9IHJ0d3NbcCArIGogKyBzXTtcbiAgICAgICAgICB2YXIgaW8gPSBpdHdzW3AgKyBqICsgc107XG5cbiAgICAgICAgICB2YXIgcnggPSBydHdkZl8gKiBybyAtIGl0d2RmXyAqIGlvO1xuXG4gICAgICAgICAgaW8gPSBydHdkZl8gKiBpbyArIGl0d2RmXyAqIHJvO1xuICAgICAgICAgIHJvID0gcng7XG5cbiAgICAgICAgICBydHdzW3AgKyBqXSA9IHJlICsgcm87XG4gICAgICAgICAgaXR3c1twICsgal0gPSBpZSArIGlvO1xuXG4gICAgICAgICAgcnR3c1twICsgaiArIHNdID0gcmUgLSBybztcbiAgICAgICAgICBpdHdzW3AgKyBqICsgc10gPSBpZSAtIGlvO1xuXG4gICAgICAgICAgLyoganNoaW50IG1heGRlcHRoIDogZmFsc2UgKi9cbiAgICAgICAgICBpZiAoaiAhPT0gbCkge1xuICAgICAgICAgICAgcnggPSBydHdkZiAqIHJ0d2RmXyAtIGl0d2RmICogaXR3ZGZfO1xuXG4gICAgICAgICAgICBpdHdkZl8gPSBydHdkZiAqIGl0d2RmXyArIGl0d2RmICogcnR3ZGZfO1xuICAgICAgICAgICAgcnR3ZGZfID0gcng7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIEZGVE0ucHJvdG90eXBlLmd1ZXNzTGVuMTNiID0gZnVuY3Rpb24gZ3Vlc3NMZW4xM2IgKG4sIG0pIHtcbiAgICB2YXIgTiA9IE1hdGgubWF4KG0sIG4pIHwgMTtcbiAgICB2YXIgb2RkID0gTiAmIDE7XG4gICAgdmFyIGkgPSAwO1xuICAgIGZvciAoTiA9IE4gLyAyIHwgMDsgTjsgTiA9IE4gPj4+IDEpIHtcbiAgICAgIGkrKztcbiAgICB9XG5cbiAgICByZXR1cm4gMSA8PCBpICsgMSArIG9kZDtcbiAgfTtcblxuICBGRlRNLnByb3RvdHlwZS5jb25qdWdhdGUgPSBmdW5jdGlvbiBjb25qdWdhdGUgKHJ3cywgaXdzLCBOKSB7XG4gICAgaWYgKE4gPD0gMSkgcmV0dXJuO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBOIC8gMjsgaSsrKSB7XG4gICAgICB2YXIgdCA9IHJ3c1tpXTtcblxuICAgICAgcndzW2ldID0gcndzW04gLSBpIC0gMV07XG4gICAgICByd3NbTiAtIGkgLSAxXSA9IHQ7XG5cbiAgICAgIHQgPSBpd3NbaV07XG5cbiAgICAgIGl3c1tpXSA9IC1pd3NbTiAtIGkgLSAxXTtcbiAgICAgIGl3c1tOIC0gaSAtIDFdID0gLXQ7XG4gICAgfVxuICB9O1xuXG4gIEZGVE0ucHJvdG90eXBlLm5vcm1hbGl6ZTEzYiA9IGZ1bmN0aW9uIG5vcm1hbGl6ZTEzYiAod3MsIE4pIHtcbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgTiAvIDI7IGkrKykge1xuICAgICAgdmFyIHcgPSBNYXRoLnJvdW5kKHdzWzIgKiBpICsgMV0gLyBOKSAqIDB4MjAwMCArXG4gICAgICAgIE1hdGgucm91bmQod3NbMiAqIGldIC8gTikgK1xuICAgICAgICBjYXJyeTtcblxuICAgICAgd3NbaV0gPSB3ICYgMHgzZmZmZmZmO1xuXG4gICAgICBpZiAodyA8IDB4NDAwMDAwMCkge1xuICAgICAgICBjYXJyeSA9IDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYXJyeSA9IHcgLyAweDQwMDAwMDAgfCAwO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB3cztcbiAgfTtcblxuICBGRlRNLnByb3RvdHlwZS5jb252ZXJ0MTNiID0gZnVuY3Rpb24gY29udmVydDEzYiAod3MsIGxlbiwgcndzLCBOKSB7XG4gICAgdmFyIGNhcnJ5ID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBjYXJyeSA9IGNhcnJ5ICsgKHdzW2ldIHwgMCk7XG5cbiAgICAgIHJ3c1syICogaV0gPSBjYXJyeSAmIDB4MWZmZjsgY2FycnkgPSBjYXJyeSA+Pj4gMTM7XG4gICAgICByd3NbMiAqIGkgKyAxXSA9IGNhcnJ5ICYgMHgxZmZmOyBjYXJyeSA9IGNhcnJ5ID4+PiAxMztcbiAgICB9XG5cbiAgICAvLyBQYWQgd2l0aCB6ZXJvZXNcbiAgICBmb3IgKGkgPSAyICogbGVuOyBpIDwgTjsgKytpKSB7XG4gICAgICByd3NbaV0gPSAwO1xuICAgIH1cblxuICAgIGFzc2VydChjYXJyeSA9PT0gMCk7XG4gICAgYXNzZXJ0KChjYXJyeSAmIH4weDFmZmYpID09PSAwKTtcbiAgfTtcblxuICBGRlRNLnByb3RvdHlwZS5zdHViID0gZnVuY3Rpb24gc3R1YiAoTikge1xuICAgIHZhciBwaCA9IG5ldyBBcnJheShOKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IE47IGkrKykge1xuICAgICAgcGhbaV0gPSAwO1xuICAgIH1cblxuICAgIHJldHVybiBwaDtcbiAgfTtcblxuICBGRlRNLnByb3RvdHlwZS5tdWxwID0gZnVuY3Rpb24gbXVscCAoeCwgeSwgb3V0KSB7XG4gICAgdmFyIE4gPSAyICogdGhpcy5ndWVzc0xlbjEzYih4Lmxlbmd0aCwgeS5sZW5ndGgpO1xuXG4gICAgdmFyIHJidCA9IHRoaXMubWFrZVJCVChOKTtcblxuICAgIHZhciBfID0gdGhpcy5zdHViKE4pO1xuXG4gICAgdmFyIHJ3cyA9IG5ldyBBcnJheShOKTtcbiAgICB2YXIgcndzdCA9IG5ldyBBcnJheShOKTtcbiAgICB2YXIgaXdzdCA9IG5ldyBBcnJheShOKTtcblxuICAgIHZhciBucndzID0gbmV3IEFycmF5KE4pO1xuICAgIHZhciBucndzdCA9IG5ldyBBcnJheShOKTtcbiAgICB2YXIgbml3c3QgPSBuZXcgQXJyYXkoTik7XG5cbiAgICB2YXIgcm13cyA9IG91dC53b3JkcztcbiAgICBybXdzLmxlbmd0aCA9IE47XG5cbiAgICB0aGlzLmNvbnZlcnQxM2IoeC53b3JkcywgeC5sZW5ndGgsIHJ3cywgTik7XG4gICAgdGhpcy5jb252ZXJ0MTNiKHkud29yZHMsIHkubGVuZ3RoLCBucndzLCBOKTtcblxuICAgIHRoaXMudHJhbnNmb3JtKHJ3cywgXywgcndzdCwgaXdzdCwgTiwgcmJ0KTtcbiAgICB0aGlzLnRyYW5zZm9ybShucndzLCBfLCBucndzdCwgbml3c3QsIE4sIHJidCk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IE47IGkrKykge1xuICAgICAgdmFyIHJ4ID0gcndzdFtpXSAqIG5yd3N0W2ldIC0gaXdzdFtpXSAqIG5pd3N0W2ldO1xuICAgICAgaXdzdFtpXSA9IHJ3c3RbaV0gKiBuaXdzdFtpXSArIGl3c3RbaV0gKiBucndzdFtpXTtcbiAgICAgIHJ3c3RbaV0gPSByeDtcbiAgICB9XG5cbiAgICB0aGlzLmNvbmp1Z2F0ZShyd3N0LCBpd3N0LCBOKTtcbiAgICB0aGlzLnRyYW5zZm9ybShyd3N0LCBpd3N0LCBybXdzLCBfLCBOLCByYnQpO1xuICAgIHRoaXMuY29uanVnYXRlKHJtd3MsIF8sIE4pO1xuICAgIHRoaXMubm9ybWFsaXplMTNiKHJtd3MsIE4pO1xuXG4gICAgb3V0Lm5lZ2F0aXZlID0geC5uZWdhdGl2ZSBeIHkubmVnYXRpdmU7XG4gICAgb3V0Lmxlbmd0aCA9IHgubGVuZ3RoICsgeS5sZW5ndGg7XG4gICAgcmV0dXJuIG91dC5zdHJpcCgpO1xuICB9O1xuXG4gIC8vIE11bHRpcGx5IGB0aGlzYCBieSBgbnVtYFxuICBCTi5wcm90b3R5cGUubXVsID0gZnVuY3Rpb24gbXVsIChudW0pIHtcbiAgICB2YXIgb3V0ID0gbmV3IEJOKG51bGwpO1xuICAgIG91dC53b3JkcyA9IG5ldyBBcnJheSh0aGlzLmxlbmd0aCArIG51bS5sZW5ndGgpO1xuICAgIHJldHVybiB0aGlzLm11bFRvKG51bSwgb3V0KTtcbiAgfTtcblxuICAvLyBNdWx0aXBseSBlbXBsb3lpbmcgRkZUXG4gIEJOLnByb3RvdHlwZS5tdWxmID0gZnVuY3Rpb24gbXVsZiAobnVtKSB7XG4gICAgdmFyIG91dCA9IG5ldyBCTihudWxsKTtcbiAgICBvdXQud29yZHMgPSBuZXcgQXJyYXkodGhpcy5sZW5ndGggKyBudW0ubGVuZ3RoKTtcbiAgICByZXR1cm4ganVtYm9NdWxUbyh0aGlzLCBudW0sIG91dCk7XG4gIH07XG5cbiAgLy8gSW4tcGxhY2UgTXVsdGlwbGljYXRpb25cbiAgQk4ucHJvdG90eXBlLmltdWwgPSBmdW5jdGlvbiBpbXVsIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLm11bFRvKG51bSwgdGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmltdWxuID0gZnVuY3Rpb24gaW11bG4gKG51bSkge1xuICAgIGFzc2VydCh0eXBlb2YgbnVtID09PSAnbnVtYmVyJyk7XG5cbiAgICAvLyBDYXJyeVxuICAgIHZhciBjYXJyeSA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdyA9ICh0aGlzLndvcmRzW2ldIHwgMCkgKiBudW07XG4gICAgICB2YXIgbG8gPSAodyAmIDB4M2ZmZmZmZikgKyAoY2FycnkgJiAweDNmZmZmZmYpO1xuICAgICAgY2FycnkgPj49IDI2O1xuICAgICAgY2FycnkgKz0gKHcgLyAweDQwMDAwMDApIHwgMDtcbiAgICAgIC8vIE5PVEU6IGxvIGlzIDI3Yml0IG1heGltdW1cbiAgICAgIGNhcnJ5ICs9IGxvID4+PiAyNjtcbiAgICAgIHRoaXMud29yZHNbaV0gPSBsbyAmIDB4M2ZmZmZmZjtcbiAgICB9XG5cbiAgICBpZiAoY2FycnkgIT09IDApIHtcbiAgICAgIHRoaXMud29yZHNbaV0gPSBjYXJyeTtcbiAgICAgIHRoaXMubGVuZ3RoKys7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLm11bG4gPSBmdW5jdGlvbiBtdWxuIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmltdWxuKG51bSk7XG4gIH07XG5cbiAgLy8gYHRoaXNgICogYHRoaXNgXG4gIEJOLnByb3RvdHlwZS5zcXIgPSBmdW5jdGlvbiBzcXIgKCkge1xuICAgIHJldHVybiB0aGlzLm11bCh0aGlzKTtcbiAgfTtcblxuICAvLyBgdGhpc2AgKiBgdGhpc2AgaW4tcGxhY2VcbiAgQk4ucHJvdG90eXBlLmlzcXIgPSBmdW5jdGlvbiBpc3FyICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbXVsKHRoaXMuY2xvbmUoKSk7XG4gIH07XG5cbiAgLy8gTWF0aC5wb3coYHRoaXNgLCBgbnVtYClcbiAgQk4ucHJvdG90eXBlLnBvdyA9IGZ1bmN0aW9uIHBvdyAobnVtKSB7XG4gICAgdmFyIHcgPSB0b0JpdEFycmF5KG51bSk7XG4gICAgaWYgKHcubGVuZ3RoID09PSAwKSByZXR1cm4gbmV3IEJOKDEpO1xuXG4gICAgLy8gU2tpcCBsZWFkaW5nIHplcm9lc1xuICAgIHZhciByZXMgPSB0aGlzO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdy5sZW5ndGg7IGkrKywgcmVzID0gcmVzLnNxcigpKSB7XG4gICAgICBpZiAod1tpXSAhPT0gMCkgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKCsraSA8IHcubGVuZ3RoKSB7XG4gICAgICBmb3IgKHZhciBxID0gcmVzLnNxcigpOyBpIDwgdy5sZW5ndGg7IGkrKywgcSA9IHEuc3FyKCkpIHtcbiAgICAgICAgaWYgKHdbaV0gPT09IDApIGNvbnRpbnVlO1xuXG4gICAgICAgIHJlcyA9IHJlcy5tdWwocSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcztcbiAgfTtcblxuICAvLyBTaGlmdC1sZWZ0IGluLXBsYWNlXG4gIEJOLnByb3RvdHlwZS5pdXNobG4gPSBmdW5jdGlvbiBpdXNobG4gKGJpdHMpIHtcbiAgICBhc3NlcnQodHlwZW9mIGJpdHMgPT09ICdudW1iZXInICYmIGJpdHMgPj0gMCk7XG4gICAgdmFyIHIgPSBiaXRzICUgMjY7XG4gICAgdmFyIHMgPSAoYml0cyAtIHIpIC8gMjY7XG4gICAgdmFyIGNhcnJ5TWFzayA9ICgweDNmZmZmZmYgPj4+ICgyNiAtIHIpKSA8PCAoMjYgLSByKTtcbiAgICB2YXIgaTtcblxuICAgIGlmIChyICE9PSAwKSB7XG4gICAgICB2YXIgY2FycnkgPSAwO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgbmV3Q2FycnkgPSB0aGlzLndvcmRzW2ldICYgY2FycnlNYXNrO1xuICAgICAgICB2YXIgYyA9ICgodGhpcy53b3Jkc1tpXSB8IDApIC0gbmV3Q2FycnkpIDw8IHI7XG4gICAgICAgIHRoaXMud29yZHNbaV0gPSBjIHwgY2Fycnk7XG4gICAgICAgIGNhcnJ5ID0gbmV3Q2FycnkgPj4+ICgyNiAtIHIpO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2FycnkpIHtcbiAgICAgICAgdGhpcy53b3Jkc1tpXSA9IGNhcnJ5O1xuICAgICAgICB0aGlzLmxlbmd0aCsrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzICE9PSAwKSB7XG4gICAgICBmb3IgKGkgPSB0aGlzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIHRoaXMud29yZHNbaSArIHNdID0gdGhpcy53b3Jkc1tpXTtcbiAgICAgIH1cblxuICAgICAgZm9yIChpID0gMDsgaSA8IHM7IGkrKykge1xuICAgICAgICB0aGlzLndvcmRzW2ldID0gMDtcbiAgICAgIH1cblxuICAgICAgdGhpcy5sZW5ndGggKz0gcztcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5pc2hsbiA9IGZ1bmN0aW9uIGlzaGxuIChiaXRzKSB7XG4gICAgLy8gVE9ETyhpbmR1dG55KTogaW1wbGVtZW50IG1lXG4gICAgYXNzZXJ0KHRoaXMubmVnYXRpdmUgPT09IDApO1xuICAgIHJldHVybiB0aGlzLml1c2hsbihiaXRzKTtcbiAgfTtcblxuICAvLyBTaGlmdC1yaWdodCBpbi1wbGFjZVxuICAvLyBOT1RFOiBgaGludGAgaXMgYSBsb3dlc3QgYml0IGJlZm9yZSB0cmFpbGluZyB6ZXJvZXNcbiAgLy8gTk9URTogaWYgYGV4dGVuZGVkYCBpcyBwcmVzZW50IC0gaXQgd2lsbCBiZSBmaWxsZWQgd2l0aCBkZXN0cm95ZWQgYml0c1xuICBCTi5wcm90b3R5cGUuaXVzaHJuID0gZnVuY3Rpb24gaXVzaHJuIChiaXRzLCBoaW50LCBleHRlbmRlZCkge1xuICAgIGFzc2VydCh0eXBlb2YgYml0cyA9PT0gJ251bWJlcicgJiYgYml0cyA+PSAwKTtcbiAgICB2YXIgaDtcbiAgICBpZiAoaGludCkge1xuICAgICAgaCA9IChoaW50IC0gKGhpbnQgJSAyNikpIC8gMjY7XG4gICAgfSBlbHNlIHtcbiAgICAgIGggPSAwO1xuICAgIH1cblxuICAgIHZhciByID0gYml0cyAlIDI2O1xuICAgIHZhciBzID0gTWF0aC5taW4oKGJpdHMgLSByKSAvIDI2LCB0aGlzLmxlbmd0aCk7XG4gICAgdmFyIG1hc2sgPSAweDNmZmZmZmYgXiAoKDB4M2ZmZmZmZiA+Pj4gcikgPDwgcik7XG4gICAgdmFyIG1hc2tlZFdvcmRzID0gZXh0ZW5kZWQ7XG5cbiAgICBoIC09IHM7XG4gICAgaCA9IE1hdGgubWF4KDAsIGgpO1xuXG4gICAgLy8gRXh0ZW5kZWQgbW9kZSwgY29weSBtYXNrZWQgcGFydFxuICAgIGlmIChtYXNrZWRXb3Jkcykge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzOyBpKyspIHtcbiAgICAgICAgbWFza2VkV29yZHMud29yZHNbaV0gPSB0aGlzLndvcmRzW2ldO1xuICAgICAgfVxuICAgICAgbWFza2VkV29yZHMubGVuZ3RoID0gcztcbiAgICB9XG5cbiAgICBpZiAocyA9PT0gMCkge1xuICAgICAgLy8gTm8tb3AsIHdlIHNob3VsZCBub3QgbW92ZSBhbnl0aGluZyBhdCBhbGxcbiAgICB9IGVsc2UgaWYgKHRoaXMubGVuZ3RoID4gcykge1xuICAgICAgdGhpcy5sZW5ndGggLT0gcztcbiAgICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMud29yZHNbaV0gPSB0aGlzLndvcmRzW2kgKyBzXTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy53b3Jkc1swXSA9IDA7XG4gICAgICB0aGlzLmxlbmd0aCA9IDE7XG4gICAgfVxuXG4gICAgdmFyIGNhcnJ5ID0gMDtcbiAgICBmb3IgKGkgPSB0aGlzLmxlbmd0aCAtIDE7IGkgPj0gMCAmJiAoY2FycnkgIT09IDAgfHwgaSA+PSBoKTsgaS0tKSB7XG4gICAgICB2YXIgd29yZCA9IHRoaXMud29yZHNbaV0gfCAwO1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IChjYXJyeSA8PCAoMjYgLSByKSkgfCAod29yZCA+Pj4gcik7XG4gICAgICBjYXJyeSA9IHdvcmQgJiBtYXNrO1xuICAgIH1cblxuICAgIC8vIFB1c2ggY2FycmllZCBiaXRzIGFzIGEgbWFza1xuICAgIGlmIChtYXNrZWRXb3JkcyAmJiBjYXJyeSAhPT0gMCkge1xuICAgICAgbWFza2VkV29yZHMud29yZHNbbWFza2VkV29yZHMubGVuZ3RoKytdID0gY2Fycnk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLndvcmRzWzBdID0gMDtcbiAgICAgIHRoaXMubGVuZ3RoID0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5pc2hybiA9IGZ1bmN0aW9uIGlzaHJuIChiaXRzLCBoaW50LCBleHRlbmRlZCkge1xuICAgIC8vIFRPRE8oaW5kdXRueSk6IGltcGxlbWVudCBtZVxuICAgIGFzc2VydCh0aGlzLm5lZ2F0aXZlID09PSAwKTtcbiAgICByZXR1cm4gdGhpcy5pdXNocm4oYml0cywgaGludCwgZXh0ZW5kZWQpO1xuICB9O1xuXG4gIC8vIFNoaWZ0LWxlZnRcbiAgQk4ucHJvdG90eXBlLnNobG4gPSBmdW5jdGlvbiBzaGxuIChiaXRzKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pc2hsbihiaXRzKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUudXNobG4gPSBmdW5jdGlvbiB1c2hsbiAoYml0cykge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaXVzaGxuKGJpdHMpO1xuICB9O1xuXG4gIC8vIFNoaWZ0LXJpZ2h0XG4gIEJOLnByb3RvdHlwZS5zaHJuID0gZnVuY3Rpb24gc2hybiAoYml0cykge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaXNocm4oYml0cyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnVzaHJuID0gZnVuY3Rpb24gdXNocm4gKGJpdHMpIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLml1c2hybihiaXRzKTtcbiAgfTtcblxuICAvLyBUZXN0IGlmIG4gYml0IGlzIHNldFxuICBCTi5wcm90b3R5cGUudGVzdG4gPSBmdW5jdGlvbiB0ZXN0biAoYml0KSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBiaXQgPT09ICdudW1iZXInICYmIGJpdCA+PSAwKTtcbiAgICB2YXIgciA9IGJpdCAlIDI2O1xuICAgIHZhciBzID0gKGJpdCAtIHIpIC8gMjY7XG4gICAgdmFyIHEgPSAxIDw8IHI7XG5cbiAgICAvLyBGYXN0IGNhc2U6IGJpdCBpcyBtdWNoIGhpZ2hlciB0aGFuIGFsbCBleGlzdGluZyB3b3Jkc1xuICAgIGlmICh0aGlzLmxlbmd0aCA8PSBzKSByZXR1cm4gZmFsc2U7XG5cbiAgICAvLyBDaGVjayBiaXQgYW5kIHJldHVyblxuICAgIHZhciB3ID0gdGhpcy53b3Jkc1tzXTtcblxuICAgIHJldHVybiAhISh3ICYgcSk7XG4gIH07XG5cbiAgLy8gUmV0dXJuIG9ubHkgbG93ZXJzIGJpdHMgb2YgbnVtYmVyIChpbi1wbGFjZSlcbiAgQk4ucHJvdG90eXBlLmltYXNrbiA9IGZ1bmN0aW9uIGltYXNrbiAoYml0cykge1xuICAgIGFzc2VydCh0eXBlb2YgYml0cyA9PT0gJ251bWJlcicgJiYgYml0cyA+PSAwKTtcbiAgICB2YXIgciA9IGJpdHMgJSAyNjtcbiAgICB2YXIgcyA9IChiaXRzIC0gcikgLyAyNjtcblxuICAgIGFzc2VydCh0aGlzLm5lZ2F0aXZlID09PSAwLCAnaW1hc2tuIHdvcmtzIG9ubHkgd2l0aCBwb3NpdGl2ZSBudW1iZXJzJyk7XG5cbiAgICBpZiAociAhPT0gMCkge1xuICAgICAgcysrO1xuICAgIH1cbiAgICB0aGlzLmxlbmd0aCA9IE1hdGgubWluKHMsIHRoaXMubGVuZ3RoKTtcblxuICAgIGlmIChyICE9PSAwKSB7XG4gICAgICB2YXIgbWFzayA9IDB4M2ZmZmZmZiBeICgoMHgzZmZmZmZmID4+PiByKSA8PCByKTtcbiAgICAgIHRoaXMud29yZHNbdGhpcy5sZW5ndGggLSAxXSAmPSBtYXNrO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgLy8gUmV0dXJuIG9ubHkgbG93ZXJzIGJpdHMgb2YgbnVtYmVyXG4gIEJOLnByb3RvdHlwZS5tYXNrbiA9IGZ1bmN0aW9uIG1hc2tuIChiaXRzKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pbWFza24oYml0cyk7XG4gIH07XG5cbiAgLy8gQWRkIHBsYWluIG51bWJlciBgbnVtYCB0byBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLmlhZGRuID0gZnVuY3Rpb24gaWFkZG4gKG51bSkge1xuICAgIGFzc2VydCh0eXBlb2YgbnVtID09PSAnbnVtYmVyJyk7XG4gICAgaWYgKG51bSA8IDApIHJldHVybiB0aGlzLmlzdWJuKC1udW0pO1xuXG4gICAgLy8gUG9zc2libGUgc2lnbiBjaGFuZ2VcbiAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgaWYgKHRoaXMubGVuZ3RoID09PSAxICYmICh0aGlzLndvcmRzWzBdIHwgMCkgPCBudW0pIHtcbiAgICAgICAgdGhpcy53b3Jkc1swXSA9IG51bSAtICh0aGlzLndvcmRzWzBdIHwgMCk7XG4gICAgICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDA7XG4gICAgICB0aGlzLmlzdWJuKG51bSk7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEFkZCB3aXRob3V0IGNoZWNrc1xuICAgIHJldHVybiB0aGlzLl9pYWRkbihudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5faWFkZG4gPSBmdW5jdGlvbiBfaWFkZG4gKG51bSkge1xuICAgIHRoaXMud29yZHNbMF0gKz0gbnVtO1xuXG4gICAgLy8gQ2FycnlcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoICYmIHRoaXMud29yZHNbaV0gPj0gMHg0MDAwMDAwOyBpKyspIHtcbiAgICAgIHRoaXMud29yZHNbaV0gLT0gMHg0MDAwMDAwO1xuICAgICAgaWYgKGkgPT09IHRoaXMubGVuZ3RoIC0gMSkge1xuICAgICAgICB0aGlzLndvcmRzW2kgKyAxXSA9IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLndvcmRzW2kgKyAxXSsrO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmxlbmd0aCA9IE1hdGgubWF4KHRoaXMubGVuZ3RoLCBpICsgMSk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvLyBTdWJ0cmFjdCBwbGFpbiBudW1iZXIgYG51bWAgZnJvbSBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLmlzdWJuID0gZnVuY3Rpb24gaXN1Ym4gKG51bSkge1xuICAgIGFzc2VydCh0eXBlb2YgbnVtID09PSAnbnVtYmVyJyk7XG4gICAgaWYgKG51bSA8IDApIHJldHVybiB0aGlzLmlhZGRuKC1udW0pO1xuXG4gICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgICAgdGhpcy5pYWRkbihudW0pO1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDE7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB0aGlzLndvcmRzWzBdIC09IG51bTtcblxuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMSAmJiB0aGlzLndvcmRzWzBdIDwgMCkge1xuICAgICAgdGhpcy53b3Jkc1swXSA9IC10aGlzLndvcmRzWzBdO1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIENhcnJ5XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoICYmIHRoaXMud29yZHNbaV0gPCAwOyBpKyspIHtcbiAgICAgICAgdGhpcy53b3Jkc1tpXSArPSAweDQwMDAwMDA7XG4gICAgICAgIHRoaXMud29yZHNbaSArIDFdIC09IDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuYWRkbiA9IGZ1bmN0aW9uIGFkZG4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaWFkZG4obnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuc3VibiA9IGZ1bmN0aW9uIHN1Ym4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaXN1Ym4obnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaWFicyA9IGZ1bmN0aW9uIGlhYnMgKCkge1xuICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmFicyA9IGZ1bmN0aW9uIGFicyAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pYWJzKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLl9pc2hsbnN1Ym11bCA9IGZ1bmN0aW9uIF9pc2hsbnN1Ym11bCAobnVtLCBtdWwsIHNoaWZ0KSB7XG4gICAgLy8gQmlnZ2VyIHN0b3JhZ2UgaXMgbmVlZGVkXG4gICAgdmFyIGxlbiA9IG51bS5sZW5ndGggKyBzaGlmdDtcbiAgICB2YXIgaTtcbiAgICBpZiAodGhpcy53b3Jkcy5sZW5ndGggPCBsZW4pIHtcbiAgICAgIHZhciB0ID0gbmV3IEFycmF5KGxlbik7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB0W2ldID0gdGhpcy53b3Jkc1tpXTtcbiAgICAgIH1cbiAgICAgIHRoaXMud29yZHMgPSB0O1xuICAgIH0gZWxzZSB7XG4gICAgICBpID0gdGhpcy5sZW5ndGg7XG4gICAgfVxuXG4gICAgLy8gWmVyb2lmeSByZXN0XG4gICAgdGhpcy5sZW5ndGggPSBNYXRoLm1heCh0aGlzLmxlbmd0aCwgbGVuKTtcbiAgICBmb3IgKDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMud29yZHNbaV0gPSAwO1xuICAgIH1cblxuICAgIHZhciB3O1xuICAgIHZhciBjYXJyeSA9IDA7XG4gICAgZm9yIChpID0gMDsgaSA8IG51bS5sZW5ndGg7IGkrKykge1xuICAgICAgdyA9ICh0aGlzLndvcmRzW2kgKyBzaGlmdF0gfCAwKSArIGNhcnJ5O1xuICAgICAgdmFyIHJpZ2h0ID0gKG51bS53b3Jkc1tpXSB8IDApICogbXVsO1xuICAgICAgdyAtPSByaWdodCAmIDB4M2ZmZmZmZjtcbiAgICAgIGNhcnJ5ID0gKHcgPj4gMjYpIC0gKChyaWdodCAvIDB4NDAwMDAwMCkgfCAwKTtcbiAgICAgIHRoaXMud29yZHNbaSArIHNoaWZ0XSA9IHcgJiAweDNmZmZmZmY7XG4gICAgfVxuICAgIGZvciAoOyBpIDwgdGhpcy5sZW5ndGggLSBzaGlmdDsgaSsrKSB7XG4gICAgICB3ID0gKHRoaXMud29yZHNbaSArIHNoaWZ0XSB8IDApICsgY2Fycnk7XG4gICAgICBjYXJyeSA9IHcgPj4gMjY7XG4gICAgICB0aGlzLndvcmRzW2kgKyBzaGlmdF0gPSB3ICYgMHgzZmZmZmZmO1xuICAgIH1cblxuICAgIGlmIChjYXJyeSA9PT0gMCkgcmV0dXJuIHRoaXMuc3RyaXAoKTtcblxuICAgIC8vIFN1YnRyYWN0aW9uIG92ZXJmbG93XG4gICAgYXNzZXJ0KGNhcnJ5ID09PSAtMSk7XG4gICAgY2FycnkgPSAwO1xuICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB3ID0gLSh0aGlzLndvcmRzW2ldIHwgMCkgKyBjYXJyeTtcbiAgICAgIGNhcnJ5ID0gdyA+PiAyNjtcbiAgICAgIHRoaXMud29yZHNbaV0gPSB3ICYgMHgzZmZmZmZmO1xuICAgIH1cbiAgICB0aGlzLm5lZ2F0aXZlID0gMTtcblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLl93b3JkRGl2ID0gZnVuY3Rpb24gX3dvcmREaXYgKG51bSwgbW9kZSkge1xuICAgIHZhciBzaGlmdCA9IHRoaXMubGVuZ3RoIC0gbnVtLmxlbmd0aDtcblxuICAgIHZhciBhID0gdGhpcy5jbG9uZSgpO1xuICAgIHZhciBiID0gbnVtO1xuXG4gICAgLy8gTm9ybWFsaXplXG4gICAgdmFyIGJoaSA9IGIud29yZHNbYi5sZW5ndGggLSAxXSB8IDA7XG4gICAgdmFyIGJoaUJpdHMgPSB0aGlzLl9jb3VudEJpdHMoYmhpKTtcbiAgICBzaGlmdCA9IDI2IC0gYmhpQml0cztcbiAgICBpZiAoc2hpZnQgIT09IDApIHtcbiAgICAgIGIgPSBiLnVzaGxuKHNoaWZ0KTtcbiAgICAgIGEuaXVzaGxuKHNoaWZ0KTtcbiAgICAgIGJoaSA9IGIud29yZHNbYi5sZW5ndGggLSAxXSB8IDA7XG4gICAgfVxuXG4gICAgLy8gSW5pdGlhbGl6ZSBxdW90aWVudFxuICAgIHZhciBtID0gYS5sZW5ndGggLSBiLmxlbmd0aDtcbiAgICB2YXIgcTtcblxuICAgIGlmIChtb2RlICE9PSAnbW9kJykge1xuICAgICAgcSA9IG5ldyBCTihudWxsKTtcbiAgICAgIHEubGVuZ3RoID0gbSArIDE7XG4gICAgICBxLndvcmRzID0gbmV3IEFycmF5KHEubGVuZ3RoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcS5sZW5ndGg7IGkrKykge1xuICAgICAgICBxLndvcmRzW2ldID0gMDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZGlmZiA9IGEuY2xvbmUoKS5faXNobG5zdWJtdWwoYiwgMSwgbSk7XG4gICAgaWYgKGRpZmYubmVnYXRpdmUgPT09IDApIHtcbiAgICAgIGEgPSBkaWZmO1xuICAgICAgaWYgKHEpIHtcbiAgICAgICAgcS53b3Jkc1ttXSA9IDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaiA9IG0gLSAxOyBqID49IDA7IGotLSkge1xuICAgICAgdmFyIHFqID0gKGEud29yZHNbYi5sZW5ndGggKyBqXSB8IDApICogMHg0MDAwMDAwICtcbiAgICAgICAgKGEud29yZHNbYi5sZW5ndGggKyBqIC0gMV0gfCAwKTtcblxuICAgICAgLy8gTk9URTogKHFqIC8gYmhpKSBpcyAoMHgzZmZmZmZmICogMHg0MDAwMDAwICsgMHgzZmZmZmZmKSAvIDB4MjAwMDAwMCBtYXhcbiAgICAgIC8vICgweDdmZmZmZmYpXG4gICAgICBxaiA9IE1hdGgubWluKChxaiAvIGJoaSkgfCAwLCAweDNmZmZmZmYpO1xuXG4gICAgICBhLl9pc2hsbnN1Ym11bChiLCBxaiwgaik7XG4gICAgICB3aGlsZSAoYS5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgICBxai0tO1xuICAgICAgICBhLm5lZ2F0aXZlID0gMDtcbiAgICAgICAgYS5faXNobG5zdWJtdWwoYiwgMSwgaik7XG4gICAgICAgIGlmICghYS5pc1plcm8oKSkge1xuICAgICAgICAgIGEubmVnYXRpdmUgXj0gMTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHEpIHtcbiAgICAgICAgcS53b3Jkc1tqXSA9IHFqO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAocSkge1xuICAgICAgcS5zdHJpcCgpO1xuICAgIH1cbiAgICBhLnN0cmlwKCk7XG5cbiAgICAvLyBEZW5vcm1hbGl6ZVxuICAgIGlmIChtb2RlICE9PSAnZGl2JyAmJiBzaGlmdCAhPT0gMCkge1xuICAgICAgYS5pdXNocm4oc2hpZnQpO1xuICAgIH1cblxuICAgIHJldHVybiB7IGRpdjogcSB8fCBudWxsLCBtb2Q6IGEgfTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZGl2bW9kID0gZnVuY3Rpb24gZGl2bW9kIChudW0sIG1vZGUsIHBvc2l0aXZlKSB7XG4gICAgYXNzZXJ0KCFudW0uaXNaZXJvKCkpO1xuXG4gICAgdmFyIGRpdiwgbW9kLCByZXM7XG4gICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDAgJiYgbnVtLm5lZ2F0aXZlID09PSAwKSB7XG4gICAgICByZXMgPSB0aGlzLm5lZygpLmRpdm1vZChudW0sIG1vZGUpO1xuXG4gICAgICBpZiAobW9kZSAhPT0gJ21vZCcpIHtcbiAgICAgICAgZGl2ID0gcmVzLmRpdi5uZWcoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1vZGUgIT09ICdkaXYnKSB7XG4gICAgICAgIG1vZCA9IHJlcy5tb2QubmVnKCk7XG4gICAgICAgIGlmIChwb3NpdGl2ZSAmJiBtb2QubmVnYXRpdmUgIT09IDApIHtcbiAgICAgICAgICBtb2QuaWFkZChudW0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRpdjogZGl2LFxuICAgICAgICBtb2Q6IG1vZFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5uZWdhdGl2ZSA9PT0gMCAmJiBudW0ubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIHJlcyA9IHRoaXMuZGl2bW9kKG51bS5uZWcoKSwgbW9kZSk7XG5cbiAgICAgIGlmIChtb2RlICE9PSAnbW9kJykge1xuICAgICAgICBkaXYgPSByZXMuZGl2Lm5lZygpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4geyBkaXY6IGRpdiwgbW9kOiByZXMubW9kIH07XG4gICAgfVxuXG4gICAgaWYgKCh0aGlzLm5lZ2F0aXZlICYgbnVtLm5lZ2F0aXZlKSAhPT0gMCkge1xuICAgICAgcmVzID0gdGhpcy5uZWcoKS5kaXZtb2QobnVtLm5lZygpLCBtb2RlKTtcblxuICAgICAgaWYgKG1vZGUgIT09ICdkaXYnKSB7XG4gICAgICAgIG1vZCA9IHJlcy5tb2QubmVnKCk7XG4gICAgICAgIGlmIChwb3NpdGl2ZSAmJiBtb2QubmVnYXRpdmUgIT09IDApIHtcbiAgICAgICAgICBtb2QuaXN1YihudW0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRpdjogcmVzLmRpdixcbiAgICAgICAgbW9kOiBtb2RcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gQm90aCBudW1iZXJzIGFyZSBwb3NpdGl2ZSBhdCB0aGlzIHBvaW50XG5cbiAgICAvLyBTdHJpcCBib3RoIG51bWJlcnMgdG8gYXBwcm94aW1hdGUgc2hpZnQgdmFsdWVcbiAgICBpZiAobnVtLmxlbmd0aCA+IHRoaXMubGVuZ3RoIHx8IHRoaXMuY21wKG51bSkgPCAwKSB7XG4gICAgICByZXR1cm4geyBkaXY6IG5ldyBCTigwKSwgbW9kOiB0aGlzIH07XG4gICAgfVxuXG4gICAgLy8gVmVyeSBzaG9ydCByZWR1Y3Rpb25cbiAgICBpZiAobnVtLmxlbmd0aCA9PT0gMSkge1xuICAgICAgaWYgKG1vZGUgPT09ICdkaXYnKSB7XG4gICAgICAgIHJldHVybiB7IGRpdjogdGhpcy5kaXZuKG51bS53b3Jkc1swXSksIG1vZDogbnVsbCB9O1xuICAgICAgfVxuXG4gICAgICBpZiAobW9kZSA9PT0gJ21vZCcpIHtcbiAgICAgICAgcmV0dXJuIHsgZGl2OiBudWxsLCBtb2Q6IG5ldyBCTih0aGlzLm1vZG4obnVtLndvcmRzWzBdKSkgfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGl2OiB0aGlzLmRpdm4obnVtLndvcmRzWzBdKSxcbiAgICAgICAgbW9kOiBuZXcgQk4odGhpcy5tb2RuKG51bS53b3Jkc1swXSkpXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl93b3JkRGl2KG51bSwgbW9kZSk7XG4gIH07XG5cbiAgLy8gRmluZCBgdGhpc2AgLyBgbnVtYFxuICBCTi5wcm90b3R5cGUuZGl2ID0gZnVuY3Rpb24gZGl2IChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5kaXZtb2QobnVtLCAnZGl2JywgZmFsc2UpLmRpdjtcbiAgfTtcblxuICAvLyBGaW5kIGB0aGlzYCAlIGBudW1gXG4gIEJOLnByb3RvdHlwZS5tb2QgPSBmdW5jdGlvbiBtb2QgKG51bSkge1xuICAgIHJldHVybiB0aGlzLmRpdm1vZChudW0sICdtb2QnLCBmYWxzZSkubW9kO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS51bW9kID0gZnVuY3Rpb24gdW1vZCAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuZGl2bW9kKG51bSwgJ21vZCcsIHRydWUpLm1vZDtcbiAgfTtcblxuICAvLyBGaW5kIFJvdW5kKGB0aGlzYCAvIGBudW1gKVxuICBCTi5wcm90b3R5cGUuZGl2Um91bmQgPSBmdW5jdGlvbiBkaXZSb3VuZCAobnVtKSB7XG4gICAgdmFyIGRtID0gdGhpcy5kaXZtb2QobnVtKTtcblxuICAgIC8vIEZhc3QgY2FzZSAtIGV4YWN0IGRpdmlzaW9uXG4gICAgaWYgKGRtLm1vZC5pc1plcm8oKSkgcmV0dXJuIGRtLmRpdjtcblxuICAgIHZhciBtb2QgPSBkbS5kaXYubmVnYXRpdmUgIT09IDAgPyBkbS5tb2QuaXN1YihudW0pIDogZG0ubW9kO1xuXG4gICAgdmFyIGhhbGYgPSBudW0udXNocm4oMSk7XG4gICAgdmFyIHIyID0gbnVtLmFuZGxuKDEpO1xuICAgIHZhciBjbXAgPSBtb2QuY21wKGhhbGYpO1xuXG4gICAgLy8gUm91bmQgZG93blxuICAgIGlmIChjbXAgPCAwIHx8IHIyID09PSAxICYmIGNtcCA9PT0gMCkgcmV0dXJuIGRtLmRpdjtcblxuICAgIC8vIFJvdW5kIHVwXG4gICAgcmV0dXJuIGRtLmRpdi5uZWdhdGl2ZSAhPT0gMCA/IGRtLmRpdi5pc3VibigxKSA6IGRtLmRpdi5pYWRkbigxKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUubW9kbiA9IGZ1bmN0aW9uIG1vZG4gKG51bSkge1xuICAgIGFzc2VydChudW0gPD0gMHgzZmZmZmZmKTtcbiAgICB2YXIgcCA9ICgxIDw8IDI2KSAlIG51bTtcblxuICAgIHZhciBhY2MgPSAwO1xuICAgIGZvciAodmFyIGkgPSB0aGlzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBhY2MgPSAocCAqIGFjYyArICh0aGlzLndvcmRzW2ldIHwgMCkpICUgbnVtO1xuICAgIH1cblxuICAgIHJldHVybiBhY2M7XG4gIH07XG5cbiAgLy8gSW4tcGxhY2UgZGl2aXNpb24gYnkgbnVtYmVyXG4gIEJOLnByb3RvdHlwZS5pZGl2biA9IGZ1bmN0aW9uIGlkaXZuIChudW0pIHtcbiAgICBhc3NlcnQobnVtIDw9IDB4M2ZmZmZmZik7XG5cbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIGZvciAodmFyIGkgPSB0aGlzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgdyA9ICh0aGlzLndvcmRzW2ldIHwgMCkgKyBjYXJyeSAqIDB4NDAwMDAwMDtcbiAgICAgIHRoaXMud29yZHNbaV0gPSAodyAvIG51bSkgfCAwO1xuICAgICAgY2FycnkgPSB3ICUgbnVtO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmRpdm4gPSBmdW5jdGlvbiBkaXZuIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmlkaXZuKG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmVnY2QgPSBmdW5jdGlvbiBlZ2NkIChwKSB7XG4gICAgYXNzZXJ0KHAubmVnYXRpdmUgPT09IDApO1xuICAgIGFzc2VydCghcC5pc1plcm8oKSk7XG5cbiAgICB2YXIgeCA9IHRoaXM7XG4gICAgdmFyIHkgPSBwLmNsb25lKCk7XG5cbiAgICBpZiAoeC5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgeCA9IHgudW1vZChwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgeCA9IHguY2xvbmUoKTtcbiAgICB9XG5cbiAgICAvLyBBICogeCArIEIgKiB5ID0geFxuICAgIHZhciBBID0gbmV3IEJOKDEpO1xuICAgIHZhciBCID0gbmV3IEJOKDApO1xuXG4gICAgLy8gQyAqIHggKyBEICogeSA9IHlcbiAgICB2YXIgQyA9IG5ldyBCTigwKTtcbiAgICB2YXIgRCA9IG5ldyBCTigxKTtcblxuICAgIHZhciBnID0gMDtcblxuICAgIHdoaWxlICh4LmlzRXZlbigpICYmIHkuaXNFdmVuKCkpIHtcbiAgICAgIHguaXVzaHJuKDEpO1xuICAgICAgeS5pdXNocm4oMSk7XG4gICAgICArK2c7XG4gICAgfVxuXG4gICAgdmFyIHlwID0geS5jbG9uZSgpO1xuICAgIHZhciB4cCA9IHguY2xvbmUoKTtcblxuICAgIHdoaWxlICgheC5pc1plcm8oKSkge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGltID0gMTsgKHgud29yZHNbMF0gJiBpbSkgPT09IDAgJiYgaSA8IDI2OyArK2ksIGltIDw8PSAxKTtcbiAgICAgIGlmIChpID4gMCkge1xuICAgICAgICB4Lml1c2hybihpKTtcbiAgICAgICAgd2hpbGUgKGktLSA+IDApIHtcbiAgICAgICAgICBpZiAoQS5pc09kZCgpIHx8IEIuaXNPZGQoKSkge1xuICAgICAgICAgICAgQS5pYWRkKHlwKTtcbiAgICAgICAgICAgIEIuaXN1Yih4cCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgQS5pdXNocm4oMSk7XG4gICAgICAgICAgQi5pdXNocm4oMSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIgaiA9IDAsIGptID0gMTsgKHkud29yZHNbMF0gJiBqbSkgPT09IDAgJiYgaiA8IDI2OyArK2osIGptIDw8PSAxKTtcbiAgICAgIGlmIChqID4gMCkge1xuICAgICAgICB5Lml1c2hybihqKTtcbiAgICAgICAgd2hpbGUgKGotLSA+IDApIHtcbiAgICAgICAgICBpZiAoQy5pc09kZCgpIHx8IEQuaXNPZGQoKSkge1xuICAgICAgICAgICAgQy5pYWRkKHlwKTtcbiAgICAgICAgICAgIEQuaXN1Yih4cCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgQy5pdXNocm4oMSk7XG4gICAgICAgICAgRC5pdXNocm4oMSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHguY21wKHkpID49IDApIHtcbiAgICAgICAgeC5pc3ViKHkpO1xuICAgICAgICBBLmlzdWIoQyk7XG4gICAgICAgIEIuaXN1YihEKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHkuaXN1Yih4KTtcbiAgICAgICAgQy5pc3ViKEEpO1xuICAgICAgICBELmlzdWIoQik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGE6IEMsXG4gICAgICBiOiBELFxuICAgICAgZ2NkOiB5Lml1c2hsbihnKVxuICAgIH07XG4gIH07XG5cbiAgLy8gVGhpcyBpcyByZWR1Y2VkIGluY2FybmF0aW9uIG9mIHRoZSBiaW5hcnkgRUVBXG4gIC8vIGFib3ZlLCBkZXNpZ25hdGVkIHRvIGludmVydCBtZW1iZXJzIG9mIHRoZVxuICAvLyBfcHJpbWVfIGZpZWxkcyBGKHApIGF0IGEgbWF4aW1hbCBzcGVlZFxuICBCTi5wcm90b3R5cGUuX2ludm1wID0gZnVuY3Rpb24gX2ludm1wIChwKSB7XG4gICAgYXNzZXJ0KHAubmVnYXRpdmUgPT09IDApO1xuICAgIGFzc2VydCghcC5pc1plcm8oKSk7XG5cbiAgICB2YXIgYSA9IHRoaXM7XG4gICAgdmFyIGIgPSBwLmNsb25lKCk7XG5cbiAgICBpZiAoYS5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgYSA9IGEudW1vZChwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYSA9IGEuY2xvbmUoKTtcbiAgICB9XG5cbiAgICB2YXIgeDEgPSBuZXcgQk4oMSk7XG4gICAgdmFyIHgyID0gbmV3IEJOKDApO1xuXG4gICAgdmFyIGRlbHRhID0gYi5jbG9uZSgpO1xuXG4gICAgd2hpbGUgKGEuY21wbigxKSA+IDAgJiYgYi5jbXBuKDEpID4gMCkge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGltID0gMTsgKGEud29yZHNbMF0gJiBpbSkgPT09IDAgJiYgaSA8IDI2OyArK2ksIGltIDw8PSAxKTtcbiAgICAgIGlmIChpID4gMCkge1xuICAgICAgICBhLml1c2hybihpKTtcbiAgICAgICAgd2hpbGUgKGktLSA+IDApIHtcbiAgICAgICAgICBpZiAoeDEuaXNPZGQoKSkge1xuICAgICAgICAgICAgeDEuaWFkZChkZWx0YSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgeDEuaXVzaHJuKDEpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAodmFyIGogPSAwLCBqbSA9IDE7IChiLndvcmRzWzBdICYgam0pID09PSAwICYmIGogPCAyNjsgKytqLCBqbSA8PD0gMSk7XG4gICAgICBpZiAoaiA+IDApIHtcbiAgICAgICAgYi5pdXNocm4oaik7XG4gICAgICAgIHdoaWxlIChqLS0gPiAwKSB7XG4gICAgICAgICAgaWYgKHgyLmlzT2RkKCkpIHtcbiAgICAgICAgICAgIHgyLmlhZGQoZGVsdGEpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHgyLml1c2hybigxKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoYS5jbXAoYikgPj0gMCkge1xuICAgICAgICBhLmlzdWIoYik7XG4gICAgICAgIHgxLmlzdWIoeDIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYi5pc3ViKGEpO1xuICAgICAgICB4Mi5pc3ViKHgxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcmVzO1xuICAgIGlmIChhLmNtcG4oMSkgPT09IDApIHtcbiAgICAgIHJlcyA9IHgxO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXMgPSB4MjtcbiAgICB9XG5cbiAgICBpZiAocmVzLmNtcG4oMCkgPCAwKSB7XG4gICAgICByZXMuaWFkZChwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5nY2QgPSBmdW5jdGlvbiBnY2QgKG51bSkge1xuICAgIGlmICh0aGlzLmlzWmVybygpKSByZXR1cm4gbnVtLmNsb25lKCk7XG4gICAgaWYgKG51bS5pc1plcm8oKSkgcmV0dXJuIHRoaXMuY2xvbmUoKTtcblxuICAgIHZhciBhID0gdGhpcy5jbG9uZSgpO1xuICAgIHZhciBiID0gbnVtLmNsb25lKCk7XG4gICAgYS5uZWdhdGl2ZSA9IDA7XG4gICAgYi5uZWdhdGl2ZSA9IDA7XG5cbiAgICAvLyBSZW1vdmUgY29tbW9uIGZhY3RvciBvZiB0d29cbiAgICBmb3IgKHZhciBzaGlmdCA9IDA7IGEuaXNFdmVuKCkgJiYgYi5pc0V2ZW4oKTsgc2hpZnQrKykge1xuICAgICAgYS5pdXNocm4oMSk7XG4gICAgICBiLml1c2hybigxKTtcbiAgICB9XG5cbiAgICBkbyB7XG4gICAgICB3aGlsZSAoYS5pc0V2ZW4oKSkge1xuICAgICAgICBhLml1c2hybigxKTtcbiAgICAgIH1cbiAgICAgIHdoaWxlIChiLmlzRXZlbigpKSB7XG4gICAgICAgIGIuaXVzaHJuKDEpO1xuICAgICAgfVxuXG4gICAgICB2YXIgciA9IGEuY21wKGIpO1xuICAgICAgaWYgKHIgPCAwKSB7XG4gICAgICAgIC8vIFN3YXAgYGFgIGFuZCBgYmAgdG8gbWFrZSBgYWAgYWx3YXlzIGJpZ2dlciB0aGFuIGBiYFxuICAgICAgICB2YXIgdCA9IGE7XG4gICAgICAgIGEgPSBiO1xuICAgICAgICBiID0gdDtcbiAgICAgIH0gZWxzZSBpZiAociA9PT0gMCB8fCBiLmNtcG4oMSkgPT09IDApIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGEuaXN1YihiKTtcbiAgICB9IHdoaWxlICh0cnVlKTtcblxuICAgIHJldHVybiBiLml1c2hsbihzaGlmdCk7XG4gIH07XG5cbiAgLy8gSW52ZXJ0IG51bWJlciBpbiB0aGUgZmllbGQgRihudW0pXG4gIEJOLnByb3RvdHlwZS5pbnZtID0gZnVuY3Rpb24gaW52bSAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuZWdjZChudW0pLmEudW1vZChudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5pc0V2ZW4gPSBmdW5jdGlvbiBpc0V2ZW4gKCkge1xuICAgIHJldHVybiAodGhpcy53b3Jkc1swXSAmIDEpID09PSAwO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5pc09kZCA9IGZ1bmN0aW9uIGlzT2RkICgpIHtcbiAgICByZXR1cm4gKHRoaXMud29yZHNbMF0gJiAxKSA9PT0gMTtcbiAgfTtcblxuICAvLyBBbmQgZmlyc3Qgd29yZCBhbmQgbnVtXG4gIEJOLnByb3RvdHlwZS5hbmRsbiA9IGZ1bmN0aW9uIGFuZGxuIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy53b3Jkc1swXSAmIG51bTtcbiAgfTtcblxuICAvLyBJbmNyZW1lbnQgYXQgdGhlIGJpdCBwb3NpdGlvbiBpbi1saW5lXG4gIEJOLnByb3RvdHlwZS5iaW5jbiA9IGZ1bmN0aW9uIGJpbmNuIChiaXQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGJpdCA9PT0gJ251bWJlcicpO1xuICAgIHZhciByID0gYml0ICUgMjY7XG4gICAgdmFyIHMgPSAoYml0IC0gcikgLyAyNjtcbiAgICB2YXIgcSA9IDEgPDwgcjtcblxuICAgIC8vIEZhc3QgY2FzZTogYml0IGlzIG11Y2ggaGlnaGVyIHRoYW4gYWxsIGV4aXN0aW5nIHdvcmRzXG4gICAgaWYgKHRoaXMubGVuZ3RoIDw9IHMpIHtcbiAgICAgIGZvciAodmFyIGkgPSB0aGlzLmxlbmd0aDsgaSA8IHMgKyAxOyBpKyspIHtcbiAgICAgICAgdGhpcy53b3Jkc1tpXSA9IDA7XG4gICAgICB9XG4gICAgICB0aGlzLndvcmRzW3NdIHw9IHE7XG4gICAgICB0aGlzLmxlbmd0aCA9IHMgKyAxO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gQWRkIGJpdCBhbmQgcHJvcGFnYXRlLCBpZiBuZWVkZWRcbiAgICB2YXIgY2FycnkgPSBxO1xuICAgIGZvciAoaSA9IHM7IGNhcnJ5ICE9PSAwICYmIGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdyA9IHRoaXMud29yZHNbaV0gfCAwO1xuICAgICAgdyArPSBjYXJyeTtcbiAgICAgIGNhcnJ5ID0gdyA+Pj4gMjY7XG4gICAgICB3ICY9IDB4M2ZmZmZmZjtcbiAgICAgIHRoaXMud29yZHNbaV0gPSB3O1xuICAgIH1cbiAgICBpZiAoY2FycnkgIT09IDApIHtcbiAgICAgIHRoaXMud29yZHNbaV0gPSBjYXJyeTtcbiAgICAgIHRoaXMubGVuZ3RoKys7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5pc1plcm8gPSBmdW5jdGlvbiBpc1plcm8gKCkge1xuICAgIHJldHVybiB0aGlzLmxlbmd0aCA9PT0gMSAmJiB0aGlzLndvcmRzWzBdID09PSAwO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5jbXBuID0gZnVuY3Rpb24gY21wbiAobnVtKSB7XG4gICAgdmFyIG5lZ2F0aXZlID0gbnVtIDwgMDtcblxuICAgIGlmICh0aGlzLm5lZ2F0aXZlICE9PSAwICYmICFuZWdhdGl2ZSkgcmV0dXJuIC0xO1xuICAgIGlmICh0aGlzLm5lZ2F0aXZlID09PSAwICYmIG5lZ2F0aXZlKSByZXR1cm4gMTtcblxuICAgIHRoaXMuc3RyaXAoKTtcblxuICAgIHZhciByZXM7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gMSkge1xuICAgICAgcmVzID0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKG5lZ2F0aXZlKSB7XG4gICAgICAgIG51bSA9IC1udW07XG4gICAgICB9XG5cbiAgICAgIGFzc2VydChudW0gPD0gMHgzZmZmZmZmLCAnTnVtYmVyIGlzIHRvbyBiaWcnKTtcblxuICAgICAgdmFyIHcgPSB0aGlzLndvcmRzWzBdIHwgMDtcbiAgICAgIHJlcyA9IHcgPT09IG51bSA/IDAgOiB3IDwgbnVtID8gLTEgOiAxO1xuICAgIH1cbiAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgcmVzID0gLXJlcztcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfTtcblxuICAvLyBDb21wYXJlIHR3byBudW1iZXJzIGFuZCByZXR1cm46XG4gIC8vIDEgLSBpZiBgdGhpc2AgPiBgbnVtYFxuICAvLyAwIC0gaWYgYHRoaXNgID09IGBudW1gXG4gIC8vIC0xIC0gaWYgYHRoaXNgIDwgYG51bWBcbiAgQk4ucHJvdG90eXBlLmNtcCA9IGZ1bmN0aW9uIGNtcCAobnVtKSB7XG4gICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDAgJiYgbnVtLm5lZ2F0aXZlID09PSAwKSByZXR1cm4gLTE7XG4gICAgaWYgKHRoaXMubmVnYXRpdmUgPT09IDAgJiYgbnVtLm5lZ2F0aXZlICE9PSAwKSByZXR1cm4gMTtcblxuICAgIHZhciByZXMgPSB0aGlzLnVjbXAobnVtKTtcbiAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCkgcmV0dXJuIC1yZXM7XG5cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIC8vIFVuc2lnbmVkIGNvbXBhcmlzb25cbiAgQk4ucHJvdG90eXBlLnVjbXAgPSBmdW5jdGlvbiB1Y21wIChudW0pIHtcbiAgICAvLyBBdCB0aGlzIHBvaW50IGJvdGggbnVtYmVycyBoYXZlIHRoZSBzYW1lIHNpZ25cbiAgICBpZiAodGhpcy5sZW5ndGggPiBudW0ubGVuZ3RoKSByZXR1cm4gMTtcbiAgICBpZiAodGhpcy5sZW5ndGggPCBudW0ubGVuZ3RoKSByZXR1cm4gLTE7XG5cbiAgICB2YXIgcmVzID0gMDtcbiAgICBmb3IgKHZhciBpID0gdGhpcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgdmFyIGEgPSB0aGlzLndvcmRzW2ldIHwgMDtcbiAgICAgIHZhciBiID0gbnVtLndvcmRzW2ldIHwgMDtcblxuICAgICAgaWYgKGEgPT09IGIpIGNvbnRpbnVlO1xuICAgICAgaWYgKGEgPCBiKSB7XG4gICAgICAgIHJlcyA9IC0xO1xuICAgICAgfSBlbHNlIGlmIChhID4gYikge1xuICAgICAgICByZXMgPSAxO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmd0biA9IGZ1bmN0aW9uIGd0biAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY21wbihudW0pID09PSAxO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5ndCA9IGZ1bmN0aW9uIGd0IChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXAobnVtKSA9PT0gMTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZ3RlbiA9IGZ1bmN0aW9uIGd0ZW4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNtcG4obnVtKSA+PSAwO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5ndGUgPSBmdW5jdGlvbiBndGUgKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNtcChudW0pID49IDA7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmx0biA9IGZ1bmN0aW9uIGx0biAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY21wbihudW0pID09PSAtMTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUubHQgPSBmdW5jdGlvbiBsdCAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY21wKG51bSkgPT09IC0xO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5sdGVuID0gZnVuY3Rpb24gbHRlbiAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY21wbihudW0pIDw9IDA7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmx0ZSA9IGZ1bmN0aW9uIGx0ZSAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY21wKG51bSkgPD0gMDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZXFuID0gZnVuY3Rpb24gZXFuIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXBuKG51bSkgPT09IDA7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmVxID0gZnVuY3Rpb24gZXEgKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNtcChudW0pID09PSAwO1xuICB9O1xuXG4gIC8vXG4gIC8vIEEgcmVkdWNlIGNvbnRleHQsIGNvdWxkIGJlIHVzaW5nIG1vbnRnb21lcnkgb3Igc29tZXRoaW5nIGJldHRlciwgZGVwZW5kaW5nXG4gIC8vIG9uIHRoZSBgbWAgaXRzZWxmLlxuICAvL1xuICBCTi5yZWQgPSBmdW5jdGlvbiByZWQgKG51bSkge1xuICAgIHJldHVybiBuZXcgUmVkKG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnRvUmVkID0gZnVuY3Rpb24gdG9SZWQgKGN0eCkge1xuICAgIGFzc2VydCghdGhpcy5yZWQsICdBbHJlYWR5IGEgbnVtYmVyIGluIHJlZHVjdGlvbiBjb250ZXh0Jyk7XG4gICAgYXNzZXJ0KHRoaXMubmVnYXRpdmUgPT09IDAsICdyZWQgd29ya3Mgb25seSB3aXRoIHBvc2l0aXZlcycpO1xuICAgIHJldHVybiBjdHguY29udmVydFRvKHRoaXMpLl9mb3JjZVJlZChjdHgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5mcm9tUmVkID0gZnVuY3Rpb24gZnJvbVJlZCAoKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAnZnJvbVJlZCB3b3JrcyBvbmx5IHdpdGggbnVtYmVycyBpbiByZWR1Y3Rpb24gY29udGV4dCcpO1xuICAgIHJldHVybiB0aGlzLnJlZC5jb252ZXJ0RnJvbSh0aGlzKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuX2ZvcmNlUmVkID0gZnVuY3Rpb24gX2ZvcmNlUmVkIChjdHgpIHtcbiAgICB0aGlzLnJlZCA9IGN0eDtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZm9yY2VSZWQgPSBmdW5jdGlvbiBmb3JjZVJlZCAoY3R4KSB7XG4gICAgYXNzZXJ0KCF0aGlzLnJlZCwgJ0FscmVhZHkgYSBudW1iZXIgaW4gcmVkdWN0aW9uIGNvbnRleHQnKTtcbiAgICByZXR1cm4gdGhpcy5fZm9yY2VSZWQoY3R4KTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkQWRkID0gZnVuY3Rpb24gcmVkQWRkIChudW0pIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWRBZGQgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLmFkZCh0aGlzLCBudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5yZWRJQWRkID0gZnVuY3Rpb24gcmVkSUFkZCAobnVtKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkSUFkZCB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgICByZXR1cm4gdGhpcy5yZWQuaWFkZCh0aGlzLCBudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5yZWRTdWIgPSBmdW5jdGlvbiByZWRTdWIgKG51bSkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZFN1YiB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgICByZXR1cm4gdGhpcy5yZWQuc3ViKHRoaXMsIG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZElTdWIgPSBmdW5jdGlvbiByZWRJU3ViIChudW0pIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWRJU3ViIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHJldHVybiB0aGlzLnJlZC5pc3ViKHRoaXMsIG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZFNobCA9IGZ1bmN0aW9uIHJlZFNobCAobnVtKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkU2hsIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHJldHVybiB0aGlzLnJlZC51c2hsKHRoaXMsIG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZE11bCA9IGZ1bmN0aW9uIHJlZE11bCAobnVtKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkTXVsIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkyKHRoaXMsIG51bSk7XG4gICAgcmV0dXJuIHRoaXMucmVkLm11bCh0aGlzLCBudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5yZWRJTXVsID0gZnVuY3Rpb24gcmVkSU11bCAobnVtKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkTXVsIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkyKHRoaXMsIG51bSk7XG4gICAgcmV0dXJuIHRoaXMucmVkLmltdWwodGhpcywgbnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkU3FyID0gZnVuY3Rpb24gcmVkU3FyICgpIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWRTcXIgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgdGhpcy5yZWQuX3ZlcmlmeTEodGhpcyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLnNxcih0aGlzKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkSVNxciA9IGZ1bmN0aW9uIHJlZElTcXIgKCkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZElTcXIgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgdGhpcy5yZWQuX3ZlcmlmeTEodGhpcyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLmlzcXIodGhpcyk7XG4gIH07XG5cbiAgLy8gU3F1YXJlIHJvb3Qgb3ZlciBwXG4gIEJOLnByb3RvdHlwZS5yZWRTcXJ0ID0gZnVuY3Rpb24gcmVkU3FydCAoKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkU3FydCB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgICB0aGlzLnJlZC5fdmVyaWZ5MSh0aGlzKTtcbiAgICByZXR1cm4gdGhpcy5yZWQuc3FydCh0aGlzKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkSW52bSA9IGZ1bmN0aW9uIHJlZEludm0gKCkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZEludm0gd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgdGhpcy5yZWQuX3ZlcmlmeTEodGhpcyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLmludm0odGhpcyk7XG4gIH07XG5cbiAgLy8gUmV0dXJuIG5lZ2F0aXZlIGNsb25lIG9mIGB0aGlzYCAlIGByZWQgbW9kdWxvYFxuICBCTi5wcm90b3R5cGUucmVkTmVnID0gZnVuY3Rpb24gcmVkTmVnICgpIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWROZWcgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgdGhpcy5yZWQuX3ZlcmlmeTEodGhpcyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLm5lZyh0aGlzKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkUG93ID0gZnVuY3Rpb24gcmVkUG93IChudW0pIHtcbiAgICBhc3NlcnQodGhpcy5yZWQgJiYgIW51bS5yZWQsICdyZWRQb3cobm9ybWFsTnVtKScpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkxKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnJlZC5wb3codGhpcywgbnVtKTtcbiAgfTtcblxuICAvLyBQcmltZSBudW1iZXJzIHdpdGggZWZmaWNpZW50IHJlZHVjdGlvblxuICB2YXIgcHJpbWVzID0ge1xuICAgIGsyNTY6IG51bGwsXG4gICAgcDIyNDogbnVsbCxcbiAgICBwMTkyOiBudWxsLFxuICAgIHAyNTUxOTogbnVsbFxuICB9O1xuXG4gIC8vIFBzZXVkby1NZXJzZW5uZSBwcmltZVxuICBmdW5jdGlvbiBNUHJpbWUgKG5hbWUsIHApIHtcbiAgICAvLyBQID0gMiBeIE4gLSBLXG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICB0aGlzLnAgPSBuZXcgQk4ocCwgMTYpO1xuICAgIHRoaXMubiA9IHRoaXMucC5iaXRMZW5ndGgoKTtcbiAgICB0aGlzLmsgPSBuZXcgQk4oMSkuaXVzaGxuKHRoaXMubikuaXN1Yih0aGlzLnApO1xuXG4gICAgdGhpcy50bXAgPSB0aGlzLl90bXAoKTtcbiAgfVxuXG4gIE1QcmltZS5wcm90b3R5cGUuX3RtcCA9IGZ1bmN0aW9uIF90bXAgKCkge1xuICAgIHZhciB0bXAgPSBuZXcgQk4obnVsbCk7XG4gICAgdG1wLndvcmRzID0gbmV3IEFycmF5KE1hdGguY2VpbCh0aGlzLm4gLyAxMykpO1xuICAgIHJldHVybiB0bXA7XG4gIH07XG5cbiAgTVByaW1lLnByb3RvdHlwZS5pcmVkdWNlID0gZnVuY3Rpb24gaXJlZHVjZSAobnVtKSB7XG4gICAgLy8gQXNzdW1lcyB0aGF0IGBudW1gIGlzIGxlc3MgdGhhbiBgUF4yYFxuICAgIC8vIG51bSA9IEhJICogKDIgXiBOIC0gSykgKyBISSAqIEsgKyBMTyA9IEhJICogSyArIExPIChtb2QgUClcbiAgICB2YXIgciA9IG51bTtcbiAgICB2YXIgcmxlbjtcblxuICAgIGRvIHtcbiAgICAgIHRoaXMuc3BsaXQociwgdGhpcy50bXApO1xuICAgICAgciA9IHRoaXMuaW11bEsocik7XG4gICAgICByID0gci5pYWRkKHRoaXMudG1wKTtcbiAgICAgIHJsZW4gPSByLmJpdExlbmd0aCgpO1xuICAgIH0gd2hpbGUgKHJsZW4gPiB0aGlzLm4pO1xuXG4gICAgdmFyIGNtcCA9IHJsZW4gPCB0aGlzLm4gPyAtMSA6IHIudWNtcCh0aGlzLnApO1xuICAgIGlmIChjbXAgPT09IDApIHtcbiAgICAgIHIud29yZHNbMF0gPSAwO1xuICAgICAgci5sZW5ndGggPSAxO1xuICAgIH0gZWxzZSBpZiAoY21wID4gMCkge1xuICAgICAgci5pc3ViKHRoaXMucCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHIuc3RyaXAoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcjtcbiAgfTtcblxuICBNUHJpbWUucHJvdG90eXBlLnNwbGl0ID0gZnVuY3Rpb24gc3BsaXQgKGlucHV0LCBvdXQpIHtcbiAgICBpbnB1dC5pdXNocm4odGhpcy5uLCAwLCBvdXQpO1xuICB9O1xuXG4gIE1QcmltZS5wcm90b3R5cGUuaW11bEsgPSBmdW5jdGlvbiBpbXVsSyAobnVtKSB7XG4gICAgcmV0dXJuIG51bS5pbXVsKHRoaXMuayk7XG4gIH07XG5cbiAgZnVuY3Rpb24gSzI1NiAoKSB7XG4gICAgTVByaW1lLmNhbGwoXG4gICAgICB0aGlzLFxuICAgICAgJ2syNTYnLFxuICAgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZlIGZmZmZmYzJmJyk7XG4gIH1cbiAgaW5oZXJpdHMoSzI1NiwgTVByaW1lKTtcblxuICBLMjU2LnByb3RvdHlwZS5zcGxpdCA9IGZ1bmN0aW9uIHNwbGl0IChpbnB1dCwgb3V0cHV0KSB7XG4gICAgLy8gMjU2ID0gOSAqIDI2ICsgMjJcbiAgICB2YXIgbWFzayA9IDB4M2ZmZmZmO1xuXG4gICAgdmFyIG91dExlbiA9IE1hdGgubWluKGlucHV0Lmxlbmd0aCwgOSk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvdXRMZW47IGkrKykge1xuICAgICAgb3V0cHV0LndvcmRzW2ldID0gaW5wdXQud29yZHNbaV07XG4gICAgfVxuICAgIG91dHB1dC5sZW5ndGggPSBvdXRMZW47XG5cbiAgICBpZiAoaW5wdXQubGVuZ3RoIDw9IDkpIHtcbiAgICAgIGlucHV0LndvcmRzWzBdID0gMDtcbiAgICAgIGlucHV0Lmxlbmd0aCA9IDE7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU2hpZnQgYnkgOSBsaW1ic1xuICAgIHZhciBwcmV2ID0gaW5wdXQud29yZHNbOV07XG4gICAgb3V0cHV0LndvcmRzW291dHB1dC5sZW5ndGgrK10gPSBwcmV2ICYgbWFzaztcblxuICAgIGZvciAoaSA9IDEwOyBpIDwgaW5wdXQubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBuZXh0ID0gaW5wdXQud29yZHNbaV0gfCAwO1xuICAgICAgaW5wdXQud29yZHNbaSAtIDEwXSA9ICgobmV4dCAmIG1hc2spIDw8IDQpIHwgKHByZXYgPj4+IDIyKTtcbiAgICAgIHByZXYgPSBuZXh0O1xuICAgIH1cbiAgICBpbnB1dC53b3Jkc1tpIC0gMTBdID0gcHJldiA+Pj4gMjI7XG4gICAgaW5wdXQubGVuZ3RoIC09IDk7XG4gIH07XG5cbiAgSzI1Ni5wcm90b3R5cGUuaW11bEsgPSBmdW5jdGlvbiBpbXVsSyAobnVtKSB7XG4gICAgLy8gSyA9IDB4MTAwMDAwM2QxID0gWyAweDQwLCAweDNkMSBdXG4gICAgbnVtLndvcmRzW251bS5sZW5ndGhdID0gMDtcbiAgICBudW0ud29yZHNbbnVtLmxlbmd0aCArIDFdID0gMDtcbiAgICBudW0ubGVuZ3RoICs9IDI7XG5cbiAgICAvLyBib3VuZGVkIGF0OiAweDQwICogMHgzZmZmZmZmICsgMHgzZDAgPSAweDEwMDAwMDM5MFxuICAgIHZhciBsbyA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW0ubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciB3ID0gbnVtLndvcmRzW2ldIHwgMDtcbiAgICAgIGxvICs9IHcgKiAweDNkMTtcbiAgICAgIG51bS53b3Jkc1tpXSA9IGxvICYgMHgzZmZmZmZmO1xuICAgICAgbG8gPSB3ICogMHg0MCArICgobG8gLyAweDQwMDAwMDApIHwgMCk7XG4gICAgfVxuXG4gICAgLy8gRmFzdCBsZW5ndGggcmVkdWN0aW9uXG4gICAgaWYgKG51bS53b3Jkc1tudW0ubGVuZ3RoIC0gMV0gPT09IDApIHtcbiAgICAgIG51bS5sZW5ndGgtLTtcbiAgICAgIGlmIChudW0ud29yZHNbbnVtLmxlbmd0aCAtIDFdID09PSAwKSB7XG4gICAgICAgIG51bS5sZW5ndGgtLTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bTtcbiAgfTtcblxuICBmdW5jdGlvbiBQMjI0ICgpIHtcbiAgICBNUHJpbWUuY2FsbChcbiAgICAgIHRoaXMsXG4gICAgICAncDIyNCcsXG4gICAgICAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgMDAwMDAwMDAgMDAwMDAwMDAgMDAwMDAwMDEnKTtcbiAgfVxuICBpbmhlcml0cyhQMjI0LCBNUHJpbWUpO1xuXG4gIGZ1bmN0aW9uIFAxOTIgKCkge1xuICAgIE1QcmltZS5jYWxsKFxuICAgICAgdGhpcyxcbiAgICAgICdwMTkyJyxcbiAgICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZSBmZmZmZmZmZiBmZmZmZmZmZicpO1xuICB9XG4gIGluaGVyaXRzKFAxOTIsIE1QcmltZSk7XG5cbiAgZnVuY3Rpb24gUDI1NTE5ICgpIHtcbiAgICAvLyAyIF4gMjU1IC0gMTlcbiAgICBNUHJpbWUuY2FsbChcbiAgICAgIHRoaXMsXG4gICAgICAnMjU1MTknLFxuICAgICAgJzdmZmZmZmZmZmZmZmZmZmYgZmZmZmZmZmZmZmZmZmZmZiBmZmZmZmZmZmZmZmZmZmZmIGZmZmZmZmZmZmZmZmZmZWQnKTtcbiAgfVxuICBpbmhlcml0cyhQMjU1MTksIE1QcmltZSk7XG5cbiAgUDI1NTE5LnByb3RvdHlwZS5pbXVsSyA9IGZ1bmN0aW9uIGltdWxLIChudW0pIHtcbiAgICAvLyBLID0gMHgxM1xuICAgIHZhciBjYXJyeSA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW0ubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBoaSA9IChudW0ud29yZHNbaV0gfCAwKSAqIDB4MTMgKyBjYXJyeTtcbiAgICAgIHZhciBsbyA9IGhpICYgMHgzZmZmZmZmO1xuICAgICAgaGkgPj4+PSAyNjtcblxuICAgICAgbnVtLndvcmRzW2ldID0gbG87XG4gICAgICBjYXJyeSA9IGhpO1xuICAgIH1cbiAgICBpZiAoY2FycnkgIT09IDApIHtcbiAgICAgIG51bS53b3Jkc1tudW0ubGVuZ3RoKytdID0gY2Fycnk7XG4gICAgfVxuICAgIHJldHVybiBudW07XG4gIH07XG5cbiAgLy8gRXhwb3J0ZWQgbW9zdGx5IGZvciB0ZXN0aW5nIHB1cnBvc2VzLCB1c2UgcGxhaW4gbmFtZSBpbnN0ZWFkXG4gIEJOLl9wcmltZSA9IGZ1bmN0aW9uIHByaW1lIChuYW1lKSB7XG4gICAgLy8gQ2FjaGVkIHZlcnNpb24gb2YgcHJpbWVcbiAgICBpZiAocHJpbWVzW25hbWVdKSByZXR1cm4gcHJpbWVzW25hbWVdO1xuXG4gICAgdmFyIHByaW1lO1xuICAgIGlmIChuYW1lID09PSAnazI1NicpIHtcbiAgICAgIHByaW1lID0gbmV3IEsyNTYoKTtcbiAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdwMjI0Jykge1xuICAgICAgcHJpbWUgPSBuZXcgUDIyNCgpO1xuICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ3AxOTInKSB7XG4gICAgICBwcmltZSA9IG5ldyBQMTkyKCk7XG4gICAgfSBlbHNlIGlmIChuYW1lID09PSAncDI1NTE5Jykge1xuICAgICAgcHJpbWUgPSBuZXcgUDI1NTE5KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBwcmltZSAnICsgbmFtZSk7XG4gICAgfVxuICAgIHByaW1lc1tuYW1lXSA9IHByaW1lO1xuXG4gICAgcmV0dXJuIHByaW1lO1xuICB9O1xuXG4gIC8vXG4gIC8vIEJhc2UgcmVkdWN0aW9uIGVuZ2luZVxuICAvL1xuICBmdW5jdGlvbiBSZWQgKG0pIHtcbiAgICBpZiAodHlwZW9mIG0gPT09ICdzdHJpbmcnKSB7XG4gICAgICB2YXIgcHJpbWUgPSBCTi5fcHJpbWUobSk7XG4gICAgICB0aGlzLm0gPSBwcmltZS5wO1xuICAgICAgdGhpcy5wcmltZSA9IHByaW1lO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm0gPSBtO1xuICAgICAgdGhpcy5wcmltZSA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgUmVkLnByb3RvdHlwZS5fdmVyaWZ5MSA9IGZ1bmN0aW9uIF92ZXJpZnkxIChhKSB7XG4gICAgYXNzZXJ0KGEubmVnYXRpdmUgPT09IDAsICdyZWQgd29ya3Mgb25seSB3aXRoIHBvc2l0aXZlcycpO1xuICAgIGFzc2VydChhLnJlZCwgJ3JlZCB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLl92ZXJpZnkyID0gZnVuY3Rpb24gX3ZlcmlmeTIgKGEsIGIpIHtcbiAgICBhc3NlcnQoKGEubmVnYXRpdmUgfCBiLm5lZ2F0aXZlKSA9PT0gMCwgJ3JlZCB3b3JrcyBvbmx5IHdpdGggcG9zaXRpdmVzJyk7XG4gICAgYXNzZXJ0KGEucmVkICYmIGEucmVkID09PSBiLnJlZCxcbiAgICAgICdyZWQgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5pbW9kID0gZnVuY3Rpb24gaW1vZCAoYSkge1xuICAgIGlmICh0aGlzLnByaW1lKSByZXR1cm4gdGhpcy5wcmltZS5pcmVkdWNlKGEpLl9mb3JjZVJlZCh0aGlzKTtcbiAgICByZXR1cm4gYS51bW9kKHRoaXMubSkuX2ZvcmNlUmVkKHRoaXMpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUubmVnID0gZnVuY3Rpb24gbmVnIChhKSB7XG4gICAgaWYgKGEuaXNaZXJvKCkpIHtcbiAgICAgIHJldHVybiBhLmNsb25lKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMubS5zdWIoYSkuX2ZvcmNlUmVkKHRoaXMpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gYWRkIChhLCBiKSB7XG4gICAgdGhpcy5fdmVyaWZ5MihhLCBiKTtcblxuICAgIHZhciByZXMgPSBhLmFkZChiKTtcbiAgICBpZiAocmVzLmNtcCh0aGlzLm0pID49IDApIHtcbiAgICAgIHJlcy5pc3ViKHRoaXMubSk7XG4gICAgfVxuICAgIHJldHVybiByZXMuX2ZvcmNlUmVkKHRoaXMpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuaWFkZCA9IGZ1bmN0aW9uIGlhZGQgKGEsIGIpIHtcbiAgICB0aGlzLl92ZXJpZnkyKGEsIGIpO1xuXG4gICAgdmFyIHJlcyA9IGEuaWFkZChiKTtcbiAgICBpZiAocmVzLmNtcCh0aGlzLm0pID49IDApIHtcbiAgICAgIHJlcy5pc3ViKHRoaXMubSk7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5zdWIgPSBmdW5jdGlvbiBzdWIgKGEsIGIpIHtcbiAgICB0aGlzLl92ZXJpZnkyKGEsIGIpO1xuXG4gICAgdmFyIHJlcyA9IGEuc3ViKGIpO1xuICAgIGlmIChyZXMuY21wbigwKSA8IDApIHtcbiAgICAgIHJlcy5pYWRkKHRoaXMubSk7XG4gICAgfVxuICAgIHJldHVybiByZXMuX2ZvcmNlUmVkKHRoaXMpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuaXN1YiA9IGZ1bmN0aW9uIGlzdWIgKGEsIGIpIHtcbiAgICB0aGlzLl92ZXJpZnkyKGEsIGIpO1xuXG4gICAgdmFyIHJlcyA9IGEuaXN1YihiKTtcbiAgICBpZiAocmVzLmNtcG4oMCkgPCAwKSB7XG4gICAgICByZXMuaWFkZCh0aGlzLm0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuc2hsID0gZnVuY3Rpb24gc2hsIChhLCBudW0pIHtcbiAgICB0aGlzLl92ZXJpZnkxKGEpO1xuICAgIHJldHVybiB0aGlzLmltb2QoYS51c2hsbihudW0pKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmltdWwgPSBmdW5jdGlvbiBpbXVsIChhLCBiKSB7XG4gICAgdGhpcy5fdmVyaWZ5MihhLCBiKTtcbiAgICByZXR1cm4gdGhpcy5pbW9kKGEuaW11bChiKSk7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5tdWwgPSBmdW5jdGlvbiBtdWwgKGEsIGIpIHtcbiAgICB0aGlzLl92ZXJpZnkyKGEsIGIpO1xuICAgIHJldHVybiB0aGlzLmltb2QoYS5tdWwoYikpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuaXNxciA9IGZ1bmN0aW9uIGlzcXIgKGEpIHtcbiAgICByZXR1cm4gdGhpcy5pbXVsKGEsIGEuY2xvbmUoKSk7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5zcXIgPSBmdW5jdGlvbiBzcXIgKGEpIHtcbiAgICByZXR1cm4gdGhpcy5tdWwoYSwgYSk7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5zcXJ0ID0gZnVuY3Rpb24gc3FydCAoYSkge1xuICAgIGlmIChhLmlzWmVybygpKSByZXR1cm4gYS5jbG9uZSgpO1xuXG4gICAgdmFyIG1vZDMgPSB0aGlzLm0uYW5kbG4oMyk7XG4gICAgYXNzZXJ0KG1vZDMgJSAyID09PSAxKTtcblxuICAgIC8vIEZhc3QgY2FzZVxuICAgIGlmIChtb2QzID09PSAzKSB7XG4gICAgICB2YXIgcG93ID0gdGhpcy5tLmFkZChuZXcgQk4oMSkpLml1c2hybigyKTtcbiAgICAgIHJldHVybiB0aGlzLnBvdyhhLCBwb3cpO1xuICAgIH1cblxuICAgIC8vIFRvbmVsbGktU2hhbmtzIGFsZ29yaXRobSAoVG90YWxseSB1bm9wdGltaXplZCBhbmQgc2xvdylcbiAgICAvL1xuICAgIC8vIEZpbmQgUSBhbmQgUywgdGhhdCBRICogMiBeIFMgPSAoUCAtIDEpXG4gICAgdmFyIHEgPSB0aGlzLm0uc3VibigxKTtcbiAgICB2YXIgcyA9IDA7XG4gICAgd2hpbGUgKCFxLmlzWmVybygpICYmIHEuYW5kbG4oMSkgPT09IDApIHtcbiAgICAgIHMrKztcbiAgICAgIHEuaXVzaHJuKDEpO1xuICAgIH1cbiAgICBhc3NlcnQoIXEuaXNaZXJvKCkpO1xuXG4gICAgdmFyIG9uZSA9IG5ldyBCTigxKS50b1JlZCh0aGlzKTtcbiAgICB2YXIgbk9uZSA9IG9uZS5yZWROZWcoKTtcblxuICAgIC8vIEZpbmQgcXVhZHJhdGljIG5vbi1yZXNpZHVlXG4gICAgLy8gTk9URTogTWF4IGlzIHN1Y2ggYmVjYXVzZSBvZiBnZW5lcmFsaXplZCBSaWVtYW5uIGh5cG90aGVzaXMuXG4gICAgdmFyIGxwb3cgPSB0aGlzLm0uc3VibigxKS5pdXNocm4oMSk7XG4gICAgdmFyIHogPSB0aGlzLm0uYml0TGVuZ3RoKCk7XG4gICAgeiA9IG5ldyBCTigyICogeiAqIHopLnRvUmVkKHRoaXMpO1xuXG4gICAgd2hpbGUgKHRoaXMucG93KHosIGxwb3cpLmNtcChuT25lKSAhPT0gMCkge1xuICAgICAgei5yZWRJQWRkKG5PbmUpO1xuICAgIH1cblxuICAgIHZhciBjID0gdGhpcy5wb3coeiwgcSk7XG4gICAgdmFyIHIgPSB0aGlzLnBvdyhhLCBxLmFkZG4oMSkuaXVzaHJuKDEpKTtcbiAgICB2YXIgdCA9IHRoaXMucG93KGEsIHEpO1xuICAgIHZhciBtID0gcztcbiAgICB3aGlsZSAodC5jbXAob25lKSAhPT0gMCkge1xuICAgICAgdmFyIHRtcCA9IHQ7XG4gICAgICBmb3IgKHZhciBpID0gMDsgdG1wLmNtcChvbmUpICE9PSAwOyBpKyspIHtcbiAgICAgICAgdG1wID0gdG1wLnJlZFNxcigpO1xuICAgICAgfVxuICAgICAgYXNzZXJ0KGkgPCBtKTtcbiAgICAgIHZhciBiID0gdGhpcy5wb3coYywgbmV3IEJOKDEpLml1c2hsbihtIC0gaSAtIDEpKTtcblxuICAgICAgciA9IHIucmVkTXVsKGIpO1xuICAgICAgYyA9IGIucmVkU3FyKCk7XG4gICAgICB0ID0gdC5yZWRNdWwoYyk7XG4gICAgICBtID0gaTtcbiAgICB9XG5cbiAgICByZXR1cm4gcjtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmludm0gPSBmdW5jdGlvbiBpbnZtIChhKSB7XG4gICAgdmFyIGludiA9IGEuX2ludm1wKHRoaXMubSk7XG4gICAgaWYgKGludi5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgaW52Lm5lZ2F0aXZlID0gMDtcbiAgICAgIHJldHVybiB0aGlzLmltb2QoaW52KS5yZWROZWcoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuaW1vZChpbnYpO1xuICAgIH1cbiAgfTtcblxuICBSZWQucHJvdG90eXBlLnBvdyA9IGZ1bmN0aW9uIHBvdyAoYSwgbnVtKSB7XG4gICAgaWYgKG51bS5pc1plcm8oKSkgcmV0dXJuIG5ldyBCTigxKTtcbiAgICBpZiAobnVtLmNtcG4oMSkgPT09IDApIHJldHVybiBhLmNsb25lKCk7XG5cbiAgICB2YXIgd2luZG93U2l6ZSA9IDQ7XG4gICAgdmFyIHduZCA9IG5ldyBBcnJheSgxIDw8IHdpbmRvd1NpemUpO1xuICAgIHduZFswXSA9IG5ldyBCTigxKS50b1JlZCh0aGlzKTtcbiAgICB3bmRbMV0gPSBhO1xuICAgIGZvciAodmFyIGkgPSAyOyBpIDwgd25kLmxlbmd0aDsgaSsrKSB7XG4gICAgICB3bmRbaV0gPSB0aGlzLm11bCh3bmRbaSAtIDFdLCBhKTtcbiAgICB9XG5cbiAgICB2YXIgcmVzID0gd25kWzBdO1xuICAgIHZhciBjdXJyZW50ID0gMDtcbiAgICB2YXIgY3VycmVudExlbiA9IDA7XG4gICAgdmFyIHN0YXJ0ID0gbnVtLmJpdExlbmd0aCgpICUgMjY7XG4gICAgaWYgKHN0YXJ0ID09PSAwKSB7XG4gICAgICBzdGFydCA9IDI2O1xuICAgIH1cblxuICAgIGZvciAoaSA9IG51bS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgdmFyIHdvcmQgPSBudW0ud29yZHNbaV07XG4gICAgICBmb3IgKHZhciBqID0gc3RhcnQgLSAxOyBqID49IDA7IGotLSkge1xuICAgICAgICB2YXIgYml0ID0gKHdvcmQgPj4gaikgJiAxO1xuICAgICAgICBpZiAocmVzICE9PSB3bmRbMF0pIHtcbiAgICAgICAgICByZXMgPSB0aGlzLnNxcihyZXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGJpdCA9PT0gMCAmJiBjdXJyZW50ID09PSAwKSB7XG4gICAgICAgICAgY3VycmVudExlbiA9IDA7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjdXJyZW50IDw8PSAxO1xuICAgICAgICBjdXJyZW50IHw9IGJpdDtcbiAgICAgICAgY3VycmVudExlbisrO1xuICAgICAgICBpZiAoY3VycmVudExlbiAhPT0gd2luZG93U2l6ZSAmJiAoaSAhPT0gMCB8fCBqICE9PSAwKSkgY29udGludWU7XG5cbiAgICAgICAgcmVzID0gdGhpcy5tdWwocmVzLCB3bmRbY3VycmVudF0pO1xuICAgICAgICBjdXJyZW50TGVuID0gMDtcbiAgICAgICAgY3VycmVudCA9IDA7XG4gICAgICB9XG4gICAgICBzdGFydCA9IDI2O1xuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5jb252ZXJ0VG8gPSBmdW5jdGlvbiBjb252ZXJ0VG8gKG51bSkge1xuICAgIHZhciByID0gbnVtLnVtb2QodGhpcy5tKTtcblxuICAgIHJldHVybiByID09PSBudW0gPyByLmNsb25lKCkgOiByO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuY29udmVydEZyb20gPSBmdW5jdGlvbiBjb252ZXJ0RnJvbSAobnVtKSB7XG4gICAgdmFyIHJlcyA9IG51bS5jbG9uZSgpO1xuICAgIHJlcy5yZWQgPSBudWxsO1xuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgLy9cbiAgLy8gTW9udGdvbWVyeSBtZXRob2QgZW5naW5lXG4gIC8vXG5cbiAgQk4ubW9udCA9IGZ1bmN0aW9uIG1vbnQgKG51bSkge1xuICAgIHJldHVybiBuZXcgTW9udChudW0pO1xuICB9O1xuXG4gIGZ1bmN0aW9uIE1vbnQgKG0pIHtcbiAgICBSZWQuY2FsbCh0aGlzLCBtKTtcblxuICAgIHRoaXMuc2hpZnQgPSB0aGlzLm0uYml0TGVuZ3RoKCk7XG4gICAgaWYgKHRoaXMuc2hpZnQgJSAyNiAhPT0gMCkge1xuICAgICAgdGhpcy5zaGlmdCArPSAyNiAtICh0aGlzLnNoaWZ0ICUgMjYpO1xuICAgIH1cblxuICAgIHRoaXMuciA9IG5ldyBCTigxKS5pdXNobG4odGhpcy5zaGlmdCk7XG4gICAgdGhpcy5yMiA9IHRoaXMuaW1vZCh0aGlzLnIuc3FyKCkpO1xuICAgIHRoaXMucmludiA9IHRoaXMuci5faW52bXAodGhpcy5tKTtcblxuICAgIHRoaXMubWludiA9IHRoaXMucmludi5tdWwodGhpcy5yKS5pc3VibigxKS5kaXYodGhpcy5tKTtcbiAgICB0aGlzLm1pbnYgPSB0aGlzLm1pbnYudW1vZCh0aGlzLnIpO1xuICAgIHRoaXMubWludiA9IHRoaXMuci5zdWIodGhpcy5taW52KTtcbiAgfVxuICBpbmhlcml0cyhNb250LCBSZWQpO1xuXG4gIE1vbnQucHJvdG90eXBlLmNvbnZlcnRUbyA9IGZ1bmN0aW9uIGNvbnZlcnRUbyAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuaW1vZChudW0udXNobG4odGhpcy5zaGlmdCkpO1xuICB9O1xuXG4gIE1vbnQucHJvdG90eXBlLmNvbnZlcnRGcm9tID0gZnVuY3Rpb24gY29udmVydEZyb20gKG51bSkge1xuICAgIHZhciByID0gdGhpcy5pbW9kKG51bS5tdWwodGhpcy5yaW52KSk7XG4gICAgci5yZWQgPSBudWxsO1xuICAgIHJldHVybiByO1xuICB9O1xuXG4gIE1vbnQucHJvdG90eXBlLmltdWwgPSBmdW5jdGlvbiBpbXVsIChhLCBiKSB7XG4gICAgaWYgKGEuaXNaZXJvKCkgfHwgYi5pc1plcm8oKSkge1xuICAgICAgYS53b3Jkc1swXSA9IDA7XG4gICAgICBhLmxlbmd0aCA9IDE7XG4gICAgICByZXR1cm4gYTtcbiAgICB9XG5cbiAgICB2YXIgdCA9IGEuaW11bChiKTtcbiAgICB2YXIgYyA9IHQubWFza24odGhpcy5zaGlmdCkubXVsKHRoaXMubWludikuaW1hc2tuKHRoaXMuc2hpZnQpLm11bCh0aGlzLm0pO1xuICAgIHZhciB1ID0gdC5pc3ViKGMpLml1c2hybih0aGlzLnNoaWZ0KTtcbiAgICB2YXIgcmVzID0gdTtcblxuICAgIGlmICh1LmNtcCh0aGlzLm0pID49IDApIHtcbiAgICAgIHJlcyA9IHUuaXN1Yih0aGlzLm0pO1xuICAgIH0gZWxzZSBpZiAodS5jbXBuKDApIDwgMCkge1xuICAgICAgcmVzID0gdS5pYWRkKHRoaXMubSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcy5fZm9yY2VSZWQodGhpcyk7XG4gIH07XG5cbiAgTW9udC5wcm90b3R5cGUubXVsID0gZnVuY3Rpb24gbXVsIChhLCBiKSB7XG4gICAgaWYgKGEuaXNaZXJvKCkgfHwgYi5pc1plcm8oKSkgcmV0dXJuIG5ldyBCTigwKS5fZm9yY2VSZWQodGhpcyk7XG5cbiAgICB2YXIgdCA9IGEubXVsKGIpO1xuICAgIHZhciBjID0gdC5tYXNrbih0aGlzLnNoaWZ0KS5tdWwodGhpcy5taW52KS5pbWFza24odGhpcy5zaGlmdCkubXVsKHRoaXMubSk7XG4gICAgdmFyIHUgPSB0LmlzdWIoYykuaXVzaHJuKHRoaXMuc2hpZnQpO1xuICAgIHZhciByZXMgPSB1O1xuICAgIGlmICh1LmNtcCh0aGlzLm0pID49IDApIHtcbiAgICAgIHJlcyA9IHUuaXN1Yih0aGlzLm0pO1xuICAgIH0gZWxzZSBpZiAodS5jbXBuKDApIDwgMCkge1xuICAgICAgcmVzID0gdS5pYWRkKHRoaXMubSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcy5fZm9yY2VSZWQodGhpcyk7XG4gIH07XG5cbiAgTW9udC5wcm90b3R5cGUuaW52bSA9IGZ1bmN0aW9uIGludm0gKGEpIHtcbiAgICAvLyAoQVIpXi0xICogUl4yID0gKEFeLTEgKiBSXi0xKSAqIFJeMiA9IEFeLTEgKiBSXG4gICAgdmFyIHJlcyA9IHRoaXMuaW1vZChhLl9pbnZtcCh0aGlzLm0pLm11bCh0aGlzLnIyKSk7XG4gICAgcmV0dXJuIHJlcy5fZm9yY2VSZWQodGhpcyk7XG4gIH07XG59KSh0eXBlb2YgbW9kdWxlID09PSAndW5kZWZpbmVkJyB8fCBtb2R1bGUsIHRoaXMpO1xuIiwidmFyIGJuID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciByYW5kb21CeXRlcyA9IHJlcXVpcmUoJ3JhbmRvbWJ5dGVzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGNydDtcbmZ1bmN0aW9uIGJsaW5kKHByaXYpIHtcbiAgdmFyIHIgPSBnZXRyKHByaXYpO1xuICB2YXIgYmxpbmRlciA9IHIudG9SZWQoYm4ubW9udChwcml2Lm1vZHVsdXMpKVxuICAucmVkUG93KG5ldyBibihwcml2LnB1YmxpY0V4cG9uZW50KSkuZnJvbVJlZCgpO1xuICByZXR1cm4ge1xuICAgIGJsaW5kZXI6IGJsaW5kZXIsXG4gICAgdW5ibGluZGVyOnIuaW52bShwcml2Lm1vZHVsdXMpXG4gIH07XG59XG5mdW5jdGlvbiBjcnQobXNnLCBwcml2KSB7XG4gIHZhciBibGluZHMgPSBibGluZChwcml2KTtcbiAgdmFyIGxlbiA9IHByaXYubW9kdWx1cy5ieXRlTGVuZ3RoKCk7XG4gIHZhciBtb2QgPSBibi5tb250KHByaXYubW9kdWx1cyk7XG4gIHZhciBibGluZGVkID0gbmV3IGJuKG1zZykubXVsKGJsaW5kcy5ibGluZGVyKS51bW9kKHByaXYubW9kdWx1cyk7XG4gIHZhciBjMSA9IGJsaW5kZWQudG9SZWQoYm4ubW9udChwcml2LnByaW1lMSkpO1xuICB2YXIgYzIgPSBibGluZGVkLnRvUmVkKGJuLm1vbnQocHJpdi5wcmltZTIpKTtcbiAgdmFyIHFpbnYgPSBwcml2LmNvZWZmaWNpZW50O1xuICB2YXIgcCA9IHByaXYucHJpbWUxO1xuICB2YXIgcSA9IHByaXYucHJpbWUyO1xuICB2YXIgbTEgPSBjMS5yZWRQb3cocHJpdi5leHBvbmVudDEpO1xuICB2YXIgbTIgPSBjMi5yZWRQb3cocHJpdi5leHBvbmVudDIpO1xuICBtMSA9IG0xLmZyb21SZWQoKTtcbiAgbTIgPSBtMi5mcm9tUmVkKCk7XG4gIHZhciBoID0gbTEuaXN1YihtMikuaW11bChxaW52KS51bW9kKHApO1xuICBoLmltdWwocSk7XG4gIG0yLmlhZGQoaCk7XG4gIHJldHVybiBuZXcgQnVmZmVyKG0yLmltdWwoYmxpbmRzLnVuYmxpbmRlcikudW1vZChwcml2Lm1vZHVsdXMpLnRvQXJyYXkoZmFsc2UsIGxlbikpO1xufVxuY3J0LmdldHIgPSBnZXRyO1xuZnVuY3Rpb24gZ2V0cihwcml2KSB7XG4gIHZhciBsZW4gPSBwcml2Lm1vZHVsdXMuYnl0ZUxlbmd0aCgpO1xuICB2YXIgciA9IG5ldyBibihyYW5kb21CeXRlcyhsZW4pKTtcbiAgd2hpbGUgKHIuY21wKHByaXYubW9kdWx1cykgPj0gIDAgfHwgIXIudW1vZChwcml2LnByaW1lMSkgfHwgIXIudW1vZChwcml2LnByaW1lMikpIHtcbiAgICByID0gbmV3IGJuKHJhbmRvbUJ5dGVzKGxlbikpO1xuICB9XG4gIHJldHVybiByO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZWxsaXB0aWMgPSBleHBvcnRzO1xuXG5lbGxpcHRpYy52ZXJzaW9uID0gcmVxdWlyZSgnLi4vcGFja2FnZS5qc29uJykudmVyc2lvbjtcbmVsbGlwdGljLnV0aWxzID0gcmVxdWlyZSgnLi9lbGxpcHRpYy91dGlscycpO1xuZWxsaXB0aWMucmFuZCA9IHJlcXVpcmUoJ2Jyb3JhbmQnKTtcbmVsbGlwdGljLmhtYWNEUkJHID0gcmVxdWlyZSgnLi9lbGxpcHRpYy9obWFjLWRyYmcnKTtcbmVsbGlwdGljLmN1cnZlID0gcmVxdWlyZSgnLi9lbGxpcHRpYy9jdXJ2ZScpO1xuZWxsaXB0aWMuY3VydmVzID0gcmVxdWlyZSgnLi9lbGxpcHRpYy9jdXJ2ZXMnKTtcblxuLy8gUHJvdG9jb2xzXG5lbGxpcHRpYy5lYyA9IHJlcXVpcmUoJy4vZWxsaXB0aWMvZWMnKTtcbmVsbGlwdGljLmVkZHNhID0gcmVxdWlyZSgnLi9lbGxpcHRpYy9lZGRzYScpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIGVsbGlwdGljID0gcmVxdWlyZSgnLi4vLi4vZWxsaXB0aWMnKTtcbnZhciB1dGlscyA9IGVsbGlwdGljLnV0aWxzO1xudmFyIGdldE5BRiA9IHV0aWxzLmdldE5BRjtcbnZhciBnZXRKU0YgPSB1dGlscy5nZXRKU0Y7XG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xuXG5mdW5jdGlvbiBCYXNlQ3VydmUodHlwZSwgY29uZikge1xuICB0aGlzLnR5cGUgPSB0eXBlO1xuICB0aGlzLnAgPSBuZXcgQk4oY29uZi5wLCAxNik7XG5cbiAgLy8gVXNlIE1vbnRnb21lcnksIHdoZW4gdGhlcmUgaXMgbm8gZmFzdCByZWR1Y3Rpb24gZm9yIHRoZSBwcmltZVxuICB0aGlzLnJlZCA9IGNvbmYucHJpbWUgPyBCTi5yZWQoY29uZi5wcmltZSkgOiBCTi5tb250KHRoaXMucCk7XG5cbiAgLy8gVXNlZnVsIGZvciBtYW55IGN1cnZlc1xuICB0aGlzLnplcm8gPSBuZXcgQk4oMCkudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLm9uZSA9IG5ldyBCTigxKS50b1JlZCh0aGlzLnJlZCk7XG4gIHRoaXMudHdvID0gbmV3IEJOKDIpLnRvUmVkKHRoaXMucmVkKTtcblxuICAvLyBDdXJ2ZSBjb25maWd1cmF0aW9uLCBvcHRpb25hbFxuICB0aGlzLm4gPSBjb25mLm4gJiYgbmV3IEJOKGNvbmYubiwgMTYpO1xuICB0aGlzLmcgPSBjb25mLmcgJiYgdGhpcy5wb2ludEZyb21KU09OKGNvbmYuZywgY29uZi5nUmVkKTtcblxuICAvLyBUZW1wb3JhcnkgYXJyYXlzXG4gIHRoaXMuX3duYWZUMSA9IG5ldyBBcnJheSg0KTtcbiAgdGhpcy5fd25hZlQyID0gbmV3IEFycmF5KDQpO1xuICB0aGlzLl93bmFmVDMgPSBuZXcgQXJyYXkoNCk7XG4gIHRoaXMuX3duYWZUNCA9IG5ldyBBcnJheSg0KTtcbn1cbm1vZHVsZS5leHBvcnRzID0gQmFzZUN1cnZlO1xuXG5CYXNlQ3VydmUucHJvdG90eXBlLnBvaW50ID0gZnVuY3Rpb24gcG9pbnQoKSB7XG4gIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG59O1xuXG5CYXNlQ3VydmUucHJvdG90eXBlLnZhbGlkYXRlID0gZnVuY3Rpb24gdmFsaWRhdGUoKSB7XG4gIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG59O1xuXG5CYXNlQ3VydmUucHJvdG90eXBlLl9maXhlZE5hZk11bCA9IGZ1bmN0aW9uIF9maXhlZE5hZk11bChwLCBrKSB7XG4gIGFzc2VydChwLnByZWNvbXB1dGVkKTtcbiAgdmFyIGRvdWJsZXMgPSBwLl9nZXREb3VibGVzKCk7XG5cbiAgdmFyIG5hZiA9IGdldE5BRihrLCAxKTtcbiAgdmFyIEkgPSAoMSA8PCAoZG91Ymxlcy5zdGVwICsgMSkpIC0gKGRvdWJsZXMuc3RlcCAlIDIgPT09IDAgPyAyIDogMSk7XG4gIEkgLz0gMztcblxuICAvLyBUcmFuc2xhdGUgaW50byBtb3JlIHdpbmRvd2VkIGZvcm1cbiAgdmFyIHJlcHIgPSBbXTtcbiAgZm9yICh2YXIgaiA9IDA7IGogPCBuYWYubGVuZ3RoOyBqICs9IGRvdWJsZXMuc3RlcCkge1xuICAgIHZhciBuYWZXID0gMDtcbiAgICBmb3IgKHZhciBrID0gaiArIGRvdWJsZXMuc3RlcCAtIDE7IGsgPj0gajsgay0tKVxuICAgICAgbmFmVyA9IChuYWZXIDw8IDEpICsgbmFmW2tdO1xuICAgIHJlcHIucHVzaChuYWZXKTtcbiAgfVxuXG4gIHZhciBhID0gdGhpcy5qcG9pbnQobnVsbCwgbnVsbCwgbnVsbCk7XG4gIHZhciBiID0gdGhpcy5qcG9pbnQobnVsbCwgbnVsbCwgbnVsbCk7XG4gIGZvciAodmFyIGkgPSBJOyBpID4gMDsgaS0tKSB7XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCByZXByLmxlbmd0aDsgaisrKSB7XG4gICAgICB2YXIgbmFmVyA9IHJlcHJbal07XG4gICAgICBpZiAobmFmVyA9PT0gaSlcbiAgICAgICAgYiA9IGIubWl4ZWRBZGQoZG91Ymxlcy5wb2ludHNbal0pO1xuICAgICAgZWxzZSBpZiAobmFmVyA9PT0gLWkpXG4gICAgICAgIGIgPSBiLm1peGVkQWRkKGRvdWJsZXMucG9pbnRzW2pdLm5lZygpKTtcbiAgICB9XG4gICAgYSA9IGEuYWRkKGIpO1xuICB9XG4gIHJldHVybiBhLnRvUCgpO1xufTtcblxuQmFzZUN1cnZlLnByb3RvdHlwZS5fd25hZk11bCA9IGZ1bmN0aW9uIF93bmFmTXVsKHAsIGspIHtcbiAgdmFyIHcgPSA0O1xuXG4gIC8vIFByZWNvbXB1dGUgd2luZG93XG4gIHZhciBuYWZQb2ludHMgPSBwLl9nZXROQUZQb2ludHModyk7XG4gIHcgPSBuYWZQb2ludHMud25kO1xuICB2YXIgd25kID0gbmFmUG9pbnRzLnBvaW50cztcblxuICAvLyBHZXQgTkFGIGZvcm1cbiAgdmFyIG5hZiA9IGdldE5BRihrLCB3KTtcblxuICAvLyBBZGQgYHRoaXNgKihOKzEpIGZvciBldmVyeSB3LU5BRiBpbmRleFxuICB2YXIgYWNjID0gdGhpcy5qcG9pbnQobnVsbCwgbnVsbCwgbnVsbCk7XG4gIGZvciAodmFyIGkgPSBuYWYubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAvLyBDb3VudCB6ZXJvZXNcbiAgICBmb3IgKHZhciBrID0gMDsgaSA+PSAwICYmIG5hZltpXSA9PT0gMDsgaS0tKVxuICAgICAgaysrO1xuICAgIGlmIChpID49IDApXG4gICAgICBrKys7XG4gICAgYWNjID0gYWNjLmRibHAoayk7XG5cbiAgICBpZiAoaSA8IDApXG4gICAgICBicmVhaztcbiAgICB2YXIgeiA9IG5hZltpXTtcbiAgICBhc3NlcnQoeiAhPT0gMCk7XG4gICAgaWYgKHAudHlwZSA9PT0gJ2FmZmluZScpIHtcbiAgICAgIC8vIEogKy0gUFxuICAgICAgaWYgKHogPiAwKVxuICAgICAgICBhY2MgPSBhY2MubWl4ZWRBZGQod25kWyh6IC0gMSkgPj4gMV0pO1xuICAgICAgZWxzZVxuICAgICAgICBhY2MgPSBhY2MubWl4ZWRBZGQod25kWygteiAtIDEpID4+IDFdLm5lZygpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSiArLSBKXG4gICAgICBpZiAoeiA+IDApXG4gICAgICAgIGFjYyA9IGFjYy5hZGQod25kWyh6IC0gMSkgPj4gMV0pO1xuICAgICAgZWxzZVxuICAgICAgICBhY2MgPSBhY2MuYWRkKHduZFsoLXogLSAxKSA+PiAxXS5uZWcoKSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBwLnR5cGUgPT09ICdhZmZpbmUnID8gYWNjLnRvUCgpIDogYWNjO1xufTtcblxuQmFzZUN1cnZlLnByb3RvdHlwZS5fd25hZk11bEFkZCA9IGZ1bmN0aW9uIF93bmFmTXVsQWRkKGRlZlcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZWZmcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW4pIHtcbiAgdmFyIHduZFdpZHRoID0gdGhpcy5fd25hZlQxO1xuICB2YXIgd25kID0gdGhpcy5fd25hZlQyO1xuICB2YXIgbmFmID0gdGhpcy5fd25hZlQzO1xuXG4gIC8vIEZpbGwgYWxsIGFycmF5c1xuICB2YXIgbWF4ID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIHZhciBwID0gcG9pbnRzW2ldO1xuICAgIHZhciBuYWZQb2ludHMgPSBwLl9nZXROQUZQb2ludHMoZGVmVyk7XG4gICAgd25kV2lkdGhbaV0gPSBuYWZQb2ludHMud25kO1xuICAgIHduZFtpXSA9IG5hZlBvaW50cy5wb2ludHM7XG4gIH1cblxuICAvLyBDb21iIHNtYWxsIHdpbmRvdyBOQUZzXG4gIGZvciAodmFyIGkgPSBsZW4gLSAxOyBpID49IDE7IGkgLT0gMikge1xuICAgIHZhciBhID0gaSAtIDE7XG4gICAgdmFyIGIgPSBpO1xuICAgIGlmICh3bmRXaWR0aFthXSAhPT0gMSB8fCB3bmRXaWR0aFtiXSAhPT0gMSkge1xuICAgICAgbmFmW2FdID0gZ2V0TkFGKGNvZWZmc1thXSwgd25kV2lkdGhbYV0pO1xuICAgICAgbmFmW2JdID0gZ2V0TkFGKGNvZWZmc1tiXSwgd25kV2lkdGhbYl0pO1xuICAgICAgbWF4ID0gTWF0aC5tYXgobmFmW2FdLmxlbmd0aCwgbWF4KTtcbiAgICAgIG1heCA9IE1hdGgubWF4KG5hZltiXS5sZW5ndGgsIG1heCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICB2YXIgY29tYiA9IFtcbiAgICAgIHBvaW50c1thXSwgLyogMSAqL1xuICAgICAgbnVsbCwgLyogMyAqL1xuICAgICAgbnVsbCwgLyogNSAqL1xuICAgICAgcG9pbnRzW2JdIC8qIDcgKi9cbiAgICBdO1xuXG4gICAgLy8gVHJ5IHRvIGF2b2lkIFByb2plY3RpdmUgcG9pbnRzLCBpZiBwb3NzaWJsZVxuICAgIGlmIChwb2ludHNbYV0ueS5jbXAocG9pbnRzW2JdLnkpID09PSAwKSB7XG4gICAgICBjb21iWzFdID0gcG9pbnRzW2FdLmFkZChwb2ludHNbYl0pO1xuICAgICAgY29tYlsyXSA9IHBvaW50c1thXS50b0ooKS5taXhlZEFkZChwb2ludHNbYl0ubmVnKCkpO1xuICAgIH0gZWxzZSBpZiAocG9pbnRzW2FdLnkuY21wKHBvaW50c1tiXS55LnJlZE5lZygpKSA9PT0gMCkge1xuICAgICAgY29tYlsxXSA9IHBvaW50c1thXS50b0ooKS5taXhlZEFkZChwb2ludHNbYl0pO1xuICAgICAgY29tYlsyXSA9IHBvaW50c1thXS5hZGQocG9pbnRzW2JdLm5lZygpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29tYlsxXSA9IHBvaW50c1thXS50b0ooKS5taXhlZEFkZChwb2ludHNbYl0pO1xuICAgICAgY29tYlsyXSA9IHBvaW50c1thXS50b0ooKS5taXhlZEFkZChwb2ludHNbYl0ubmVnKCkpO1xuICAgIH1cblxuICAgIHZhciBpbmRleCA9IFtcbiAgICAgIC0zLCAvKiAtMSAtMSAqL1xuICAgICAgLTEsIC8qIC0xIDAgKi9cbiAgICAgIC01LCAvKiAtMSAxICovXG4gICAgICAtNywgLyogMCAtMSAqL1xuICAgICAgMCwgLyogMCAwICovXG4gICAgICA3LCAvKiAwIDEgKi9cbiAgICAgIDUsIC8qIDEgLTEgKi9cbiAgICAgIDEsIC8qIDEgMCAqL1xuICAgICAgMyAgLyogMSAxICovXG4gICAgXTtcblxuICAgIHZhciBqc2YgPSBnZXRKU0YoY29lZmZzW2FdLCBjb2VmZnNbYl0pO1xuICAgIG1heCA9IE1hdGgubWF4KGpzZlswXS5sZW5ndGgsIG1heCk7XG4gICAgbmFmW2FdID0gbmV3IEFycmF5KG1heCk7XG4gICAgbmFmW2JdID0gbmV3IEFycmF5KG1heCk7XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBtYXg7IGorKykge1xuICAgICAgdmFyIGphID0ganNmWzBdW2pdIHwgMDtcbiAgICAgIHZhciBqYiA9IGpzZlsxXVtqXSB8IDA7XG5cbiAgICAgIG5hZlthXVtqXSA9IGluZGV4WyhqYSArIDEpICogMyArIChqYiArIDEpXTtcbiAgICAgIG5hZltiXVtqXSA9IDA7XG4gICAgICB3bmRbYV0gPSBjb21iO1xuICAgIH1cbiAgfVxuXG4gIHZhciBhY2MgPSB0aGlzLmpwb2ludChudWxsLCBudWxsLCBudWxsKTtcbiAgdmFyIHRtcCA9IHRoaXMuX3duYWZUNDtcbiAgZm9yICh2YXIgaSA9IG1heDsgaSA+PSAwOyBpLS0pIHtcbiAgICB2YXIgayA9IDA7XG5cbiAgICB3aGlsZSAoaSA+PSAwKSB7XG4gICAgICB2YXIgemVybyA9IHRydWU7XG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGxlbjsgaisrKSB7XG4gICAgICAgIHRtcFtqXSA9IG5hZltqXVtpXSB8IDA7XG4gICAgICAgIGlmICh0bXBbal0gIT09IDApXG4gICAgICAgICAgemVybyA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKCF6ZXJvKVxuICAgICAgICBicmVhaztcbiAgICAgIGsrKztcbiAgICAgIGktLTtcbiAgICB9XG4gICAgaWYgKGkgPj0gMClcbiAgICAgIGsrKztcbiAgICBhY2MgPSBhY2MuZGJscChrKTtcbiAgICBpZiAoaSA8IDApXG4gICAgICBicmVhaztcblxuICAgIGZvciAodmFyIGogPSAwOyBqIDwgbGVuOyBqKyspIHtcbiAgICAgIHZhciB6ID0gdG1wW2pdO1xuICAgICAgdmFyIHA7XG4gICAgICBpZiAoeiA9PT0gMClcbiAgICAgICAgY29udGludWU7XG4gICAgICBlbHNlIGlmICh6ID4gMClcbiAgICAgICAgcCA9IHduZFtqXVsoeiAtIDEpID4+IDFdO1xuICAgICAgZWxzZSBpZiAoeiA8IDApXG4gICAgICAgIHAgPSB3bmRbal1bKC16IC0gMSkgPj4gMV0ubmVnKCk7XG5cbiAgICAgIGlmIChwLnR5cGUgPT09ICdhZmZpbmUnKVxuICAgICAgICBhY2MgPSBhY2MubWl4ZWRBZGQocCk7XG4gICAgICBlbHNlXG4gICAgICAgIGFjYyA9IGFjYy5hZGQocCk7XG4gICAgfVxuICB9XG4gIC8vIFplcm9pZnkgcmVmZXJlbmNlc1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKVxuICAgIHduZFtpXSA9IG51bGw7XG4gIHJldHVybiBhY2MudG9QKCk7XG59O1xuXG5mdW5jdGlvbiBCYXNlUG9pbnQoY3VydmUsIHR5cGUpIHtcbiAgdGhpcy5jdXJ2ZSA9IGN1cnZlO1xuICB0aGlzLnR5cGUgPSB0eXBlO1xuICB0aGlzLnByZWNvbXB1dGVkID0gbnVsbDtcbn1cbkJhc2VDdXJ2ZS5CYXNlUG9pbnQgPSBCYXNlUG9pbnQ7XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuZXEgPSBmdW5jdGlvbiBlcSgvKm90aGVyKi8pIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUudmFsaWRhdGUgPSBmdW5jdGlvbiB2YWxpZGF0ZSgpIHtcbiAgcmV0dXJuIHRoaXMuY3VydmUudmFsaWRhdGUodGhpcyk7XG59O1xuXG5CYXNlQ3VydmUucHJvdG90eXBlLmRlY29kZVBvaW50ID0gZnVuY3Rpb24gZGVjb2RlUG9pbnQoYnl0ZXMsIGVuYykge1xuICBieXRlcyA9IHV0aWxzLnRvQXJyYXkoYnl0ZXMsIGVuYyk7XG5cbiAgdmFyIGxlbiA9IHRoaXMucC5ieXRlTGVuZ3RoKCk7XG4gIGlmIChieXRlc1swXSA9PT0gMHgwNCAmJiBieXRlcy5sZW5ndGggLSAxID09PSAyICogbGVuKSB7XG4gICAgcmV0dXJuIHRoaXMucG9pbnQoYnl0ZXMuc2xpY2UoMSwgMSArIGxlbiksXG4gICAgICAgICAgICAgICAgICAgICAgYnl0ZXMuc2xpY2UoMSArIGxlbiwgMSArIDIgKiBsZW4pKTtcbiAgfSBlbHNlIGlmICgoYnl0ZXNbMF0gPT09IDB4MDIgfHwgYnl0ZXNbMF0gPT09IDB4MDMpICYmXG4gICAgICAgICAgICAgIGJ5dGVzLmxlbmd0aCAtIDEgPT09IGxlbikge1xuICAgIHJldHVybiB0aGlzLnBvaW50RnJvbVgoYnl0ZXMuc2xpY2UoMSwgMSArIGxlbiksIGJ5dGVzWzBdID09PSAweDAzKTtcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gcG9pbnQgZm9ybWF0Jyk7XG59O1xuXG5CYXNlUG9pbnQucHJvdG90eXBlLmVuY29kZUNvbXByZXNzZWQgPSBmdW5jdGlvbiBlbmNvZGVDb21wcmVzc2VkKGVuYykge1xuICByZXR1cm4gdGhpcy5lbmNvZGUoZW5jLCB0cnVlKTtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuX2VuY29kZSA9IGZ1bmN0aW9uIF9lbmNvZGUoY29tcGFjdCkge1xuICB2YXIgbGVuID0gdGhpcy5jdXJ2ZS5wLmJ5dGVMZW5ndGgoKTtcbiAgdmFyIHggPSB0aGlzLmdldFgoKS50b0FycmF5KCdiZScsIGxlbik7XG5cbiAgaWYgKGNvbXBhY3QpXG4gICAgcmV0dXJuIFsgdGhpcy5nZXRZKCkuaXNFdmVuKCkgPyAweDAyIDogMHgwMyBdLmNvbmNhdCh4KTtcblxuICByZXR1cm4gWyAweDA0IF0uY29uY2F0KHgsIHRoaXMuZ2V0WSgpLnRvQXJyYXkoJ2JlJywgbGVuKSkgO1xufTtcblxuQmFzZVBvaW50LnByb3RvdHlwZS5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUoZW5jLCBjb21wYWN0KSB7XG4gIHJldHVybiB1dGlscy5lbmNvZGUodGhpcy5fZW5jb2RlKGNvbXBhY3QpLCBlbmMpO1xufTtcblxuQmFzZVBvaW50LnByb3RvdHlwZS5wcmVjb21wdXRlID0gZnVuY3Rpb24gcHJlY29tcHV0ZShwb3dlcikge1xuICBpZiAodGhpcy5wcmVjb21wdXRlZClcbiAgICByZXR1cm4gdGhpcztcblxuICB2YXIgcHJlY29tcHV0ZWQgPSB7XG4gICAgZG91YmxlczogbnVsbCxcbiAgICBuYWY6IG51bGwsXG4gICAgYmV0YTogbnVsbFxuICB9O1xuICBwcmVjb21wdXRlZC5uYWYgPSB0aGlzLl9nZXROQUZQb2ludHMoOCk7XG4gIHByZWNvbXB1dGVkLmRvdWJsZXMgPSB0aGlzLl9nZXREb3VibGVzKDQsIHBvd2VyKTtcbiAgcHJlY29tcHV0ZWQuYmV0YSA9IHRoaXMuX2dldEJldGEoKTtcbiAgdGhpcy5wcmVjb21wdXRlZCA9IHByZWNvbXB1dGVkO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuQmFzZVBvaW50LnByb3RvdHlwZS5faGFzRG91YmxlcyA9IGZ1bmN0aW9uIF9oYXNEb3VibGVzKGspIHtcbiAgaWYgKCF0aGlzLnByZWNvbXB1dGVkKVxuICAgIHJldHVybiBmYWxzZTtcblxuICB2YXIgZG91YmxlcyA9IHRoaXMucHJlY29tcHV0ZWQuZG91YmxlcztcbiAgaWYgKCFkb3VibGVzKVxuICAgIHJldHVybiBmYWxzZTtcblxuICByZXR1cm4gZG91Ymxlcy5wb2ludHMubGVuZ3RoID49IE1hdGguY2VpbCgoay5iaXRMZW5ndGgoKSArIDEpIC8gZG91Ymxlcy5zdGVwKTtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuX2dldERvdWJsZXMgPSBmdW5jdGlvbiBfZ2V0RG91YmxlcyhzdGVwLCBwb3dlcikge1xuICBpZiAodGhpcy5wcmVjb21wdXRlZCAmJiB0aGlzLnByZWNvbXB1dGVkLmRvdWJsZXMpXG4gICAgcmV0dXJuIHRoaXMucHJlY29tcHV0ZWQuZG91YmxlcztcblxuICB2YXIgZG91YmxlcyA9IFsgdGhpcyBdO1xuICB2YXIgYWNjID0gdGhpcztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwb3dlcjsgaSArPSBzdGVwKSB7XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBzdGVwOyBqKyspXG4gICAgICBhY2MgPSBhY2MuZGJsKCk7XG4gICAgZG91Ymxlcy5wdXNoKGFjYyk7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBzdGVwOiBzdGVwLFxuICAgIHBvaW50czogZG91Ymxlc1xuICB9O1xufTtcblxuQmFzZVBvaW50LnByb3RvdHlwZS5fZ2V0TkFGUG9pbnRzID0gZnVuY3Rpb24gX2dldE5BRlBvaW50cyh3bmQpIHtcbiAgaWYgKHRoaXMucHJlY29tcHV0ZWQgJiYgdGhpcy5wcmVjb21wdXRlZC5uYWYpXG4gICAgcmV0dXJuIHRoaXMucHJlY29tcHV0ZWQubmFmO1xuXG4gIHZhciByZXMgPSBbIHRoaXMgXTtcbiAgdmFyIG1heCA9ICgxIDw8IHduZCkgLSAxO1xuICB2YXIgZGJsID0gbWF4ID09PSAxID8gbnVsbCA6IHRoaXMuZGJsKCk7XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgbWF4OyBpKyspXG4gICAgcmVzW2ldID0gcmVzW2kgLSAxXS5hZGQoZGJsKTtcbiAgcmV0dXJuIHtcbiAgICB3bmQ6IHduZCxcbiAgICBwb2ludHM6IHJlc1xuICB9O1xufTtcblxuQmFzZVBvaW50LnByb3RvdHlwZS5fZ2V0QmV0YSA9IGZ1bmN0aW9uIF9nZXRCZXRhKCkge1xuICByZXR1cm4gbnVsbDtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuZGJscCA9IGZ1bmN0aW9uIGRibHAoaykge1xuICB2YXIgciA9IHRoaXM7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgazsgaSsrKVxuICAgIHIgPSByLmRibCgpO1xuICByZXR1cm4gcjtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBjdXJ2ZSA9IHJlcXVpcmUoJy4uL2N1cnZlJyk7XG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi8uLi9lbGxpcHRpYycpO1xudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG52YXIgQmFzZSA9IGN1cnZlLmJhc2U7XG5cbnZhciBhc3NlcnQgPSBlbGxpcHRpYy51dGlscy5hc3NlcnQ7XG5cbmZ1bmN0aW9uIEVkd2FyZHNDdXJ2ZShjb25mKSB7XG4gIC8vIE5PVEU6IEltcG9ydGFudCBhcyB3ZSBhcmUgY3JlYXRpbmcgcG9pbnQgaW4gQmFzZS5jYWxsKClcbiAgdGhpcy50d2lzdGVkID0gKGNvbmYuYSB8IDApICE9PSAxO1xuICB0aGlzLm1PbmVBID0gdGhpcy50d2lzdGVkICYmIChjb25mLmEgfCAwKSA9PT0gLTE7XG4gIHRoaXMuZXh0ZW5kZWQgPSB0aGlzLm1PbmVBO1xuXG4gIEJhc2UuY2FsbCh0aGlzLCAnZWR3YXJkcycsIGNvbmYpO1xuXG4gIHRoaXMuYSA9IG5ldyBCTihjb25mLmEsIDE2KS51bW9kKHRoaXMucmVkLm0pO1xuICB0aGlzLmEgPSB0aGlzLmEudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLmMgPSBuZXcgQk4oY29uZi5jLCAxNikudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLmMyID0gdGhpcy5jLnJlZFNxcigpO1xuICB0aGlzLmQgPSBuZXcgQk4oY29uZi5kLCAxNikudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLmRkID0gdGhpcy5kLnJlZEFkZCh0aGlzLmQpO1xuXG4gIGFzc2VydCghdGhpcy50d2lzdGVkIHx8IHRoaXMuYy5mcm9tUmVkKCkuY21wbigxKSA9PT0gMCk7XG4gIHRoaXMub25lQyA9IChjb25mLmMgfCAwKSA9PT0gMTtcbn1cbmluaGVyaXRzKEVkd2FyZHNDdXJ2ZSwgQmFzZSk7XG5tb2R1bGUuZXhwb3J0cyA9IEVkd2FyZHNDdXJ2ZTtcblxuRWR3YXJkc0N1cnZlLnByb3RvdHlwZS5fbXVsQSA9IGZ1bmN0aW9uIF9tdWxBKG51bSkge1xuICBpZiAodGhpcy5tT25lQSlcbiAgICByZXR1cm4gbnVtLnJlZE5lZygpO1xuICBlbHNlXG4gICAgcmV0dXJuIHRoaXMuYS5yZWRNdWwobnVtKTtcbn07XG5cbkVkd2FyZHNDdXJ2ZS5wcm90b3R5cGUuX211bEMgPSBmdW5jdGlvbiBfbXVsQyhudW0pIHtcbiAgaWYgKHRoaXMub25lQylcbiAgICByZXR1cm4gbnVtO1xuICBlbHNlXG4gICAgcmV0dXJuIHRoaXMuYy5yZWRNdWwobnVtKTtcbn07XG5cbi8vIEp1c3QgZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBTaG9ydCBjdXJ2ZVxuRWR3YXJkc0N1cnZlLnByb3RvdHlwZS5qcG9pbnQgPSBmdW5jdGlvbiBqcG9pbnQoeCwgeSwgeiwgdCkge1xuICByZXR1cm4gdGhpcy5wb2ludCh4LCB5LCB6LCB0KTtcbn07XG5cbkVkd2FyZHNDdXJ2ZS5wcm90b3R5cGUucG9pbnRGcm9tWCA9IGZ1bmN0aW9uIHBvaW50RnJvbVgoeCwgb2RkKSB7XG4gIHggPSBuZXcgQk4oeCwgMTYpO1xuICBpZiAoIXgucmVkKVxuICAgIHggPSB4LnRvUmVkKHRoaXMucmVkKTtcblxuICB2YXIgeDIgPSB4LnJlZFNxcigpO1xuICB2YXIgcmhzID0gdGhpcy5jMi5yZWRTdWIodGhpcy5hLnJlZE11bCh4MikpO1xuICB2YXIgbGhzID0gdGhpcy5vbmUucmVkU3ViKHRoaXMuYzIucmVkTXVsKHRoaXMuZCkucmVkTXVsKHgyKSk7XG5cbiAgdmFyIHkyID0gcmhzLnJlZE11bChsaHMucmVkSW52bSgpKTtcbiAgdmFyIHkgPSB5Mi5yZWRTcXJ0KCk7XG4gIGlmICh5LnJlZFNxcigpLnJlZFN1Yih5MikuY21wKHRoaXMuemVybykgIT09IDApXG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHBvaW50Jyk7XG5cbiAgdmFyIGlzT2RkID0geS5mcm9tUmVkKCkuaXNPZGQoKTtcbiAgaWYgKG9kZCAmJiAhaXNPZGQgfHwgIW9kZCAmJiBpc09kZClcbiAgICB5ID0geS5yZWROZWcoKTtcblxuICByZXR1cm4gdGhpcy5wb2ludCh4LCB5KTtcbn07XG5cbkVkd2FyZHNDdXJ2ZS5wcm90b3R5cGUucG9pbnRGcm9tWSA9IGZ1bmN0aW9uIHBvaW50RnJvbVkoeSwgb2RkKSB7XG4gIHkgPSBuZXcgQk4oeSwgMTYpO1xuICBpZiAoIXkucmVkKVxuICAgIHkgPSB5LnRvUmVkKHRoaXMucmVkKTtcblxuICAvLyB4XjIgPSAoeV4yIC0gMSkgLyAoZCB5XjIgKyAxKVxuICB2YXIgeTIgPSB5LnJlZFNxcigpO1xuICB2YXIgbGhzID0geTIucmVkU3ViKHRoaXMub25lKTtcbiAgdmFyIHJocyA9IHkyLnJlZE11bCh0aGlzLmQpLnJlZEFkZCh0aGlzLm9uZSk7XG4gIHZhciB4MiA9IGxocy5yZWRNdWwocmhzLnJlZEludm0oKSk7XG5cbiAgaWYgKHgyLmNtcCh0aGlzLnplcm8pID09PSAwKSB7XG4gICAgaWYgKG9kZClcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBwb2ludCcpO1xuICAgIGVsc2VcbiAgICAgIHJldHVybiB0aGlzLnBvaW50KHRoaXMuemVybywgeSk7XG4gIH1cblxuICB2YXIgeCA9IHgyLnJlZFNxcnQoKTtcbiAgaWYgKHgucmVkU3FyKCkucmVkU3ViKHgyKS5jbXAodGhpcy56ZXJvKSAhPT0gMClcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgcG9pbnQnKTtcblxuICBpZiAoeC5pc09kZCgpICE9PSBvZGQpXG4gICAgeCA9IHgucmVkTmVnKCk7XG5cbiAgcmV0dXJuIHRoaXMucG9pbnQoeCwgeSk7XG59O1xuXG5FZHdhcmRzQ3VydmUucHJvdG90eXBlLnZhbGlkYXRlID0gZnVuY3Rpb24gdmFsaWRhdGUocG9pbnQpIHtcbiAgaWYgKHBvaW50LmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gdHJ1ZTtcblxuICAvLyBDdXJ2ZTogQSAqIFheMiArIFleMiA9IENeMiAqICgxICsgRCAqIFheMiAqIFleMilcbiAgcG9pbnQubm9ybWFsaXplKCk7XG5cbiAgdmFyIHgyID0gcG9pbnQueC5yZWRTcXIoKTtcbiAgdmFyIHkyID0gcG9pbnQueS5yZWRTcXIoKTtcbiAgdmFyIGxocyA9IHgyLnJlZE11bCh0aGlzLmEpLnJlZEFkZCh5Mik7XG4gIHZhciByaHMgPSB0aGlzLmMyLnJlZE11bCh0aGlzLm9uZS5yZWRBZGQodGhpcy5kLnJlZE11bCh4MikucmVkTXVsKHkyKSkpO1xuXG4gIHJldHVybiBsaHMuY21wKHJocykgPT09IDA7XG59O1xuXG5mdW5jdGlvbiBQb2ludChjdXJ2ZSwgeCwgeSwgeiwgdCkge1xuICBCYXNlLkJhc2VQb2ludC5jYWxsKHRoaXMsIGN1cnZlLCAncHJvamVjdGl2ZScpO1xuICBpZiAoeCA9PT0gbnVsbCAmJiB5ID09PSBudWxsICYmIHogPT09IG51bGwpIHtcbiAgICB0aGlzLnggPSB0aGlzLmN1cnZlLnplcm87XG4gICAgdGhpcy55ID0gdGhpcy5jdXJ2ZS5vbmU7XG4gICAgdGhpcy56ID0gdGhpcy5jdXJ2ZS5vbmU7XG4gICAgdGhpcy50ID0gdGhpcy5jdXJ2ZS56ZXJvO1xuICAgIHRoaXMuek9uZSA9IHRydWU7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy54ID0gbmV3IEJOKHgsIDE2KTtcbiAgICB0aGlzLnkgPSBuZXcgQk4oeSwgMTYpO1xuICAgIHRoaXMueiA9IHogPyBuZXcgQk4oeiwgMTYpIDogdGhpcy5jdXJ2ZS5vbmU7XG4gICAgdGhpcy50ID0gdCAmJiBuZXcgQk4odCwgMTYpO1xuICAgIGlmICghdGhpcy54LnJlZClcbiAgICAgIHRoaXMueCA9IHRoaXMueC50b1JlZCh0aGlzLmN1cnZlLnJlZCk7XG4gICAgaWYgKCF0aGlzLnkucmVkKVxuICAgICAgdGhpcy55ID0gdGhpcy55LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcbiAgICBpZiAoIXRoaXMuei5yZWQpXG4gICAgICB0aGlzLnogPSB0aGlzLnoudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICAgIGlmICh0aGlzLnQgJiYgIXRoaXMudC5yZWQpXG4gICAgICB0aGlzLnQgPSB0aGlzLnQudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICAgIHRoaXMuek9uZSA9IHRoaXMueiA9PT0gdGhpcy5jdXJ2ZS5vbmU7XG5cbiAgICAvLyBVc2UgZXh0ZW5kZWQgY29vcmRpbmF0ZXNcbiAgICBpZiAodGhpcy5jdXJ2ZS5leHRlbmRlZCAmJiAhdGhpcy50KSB7XG4gICAgICB0aGlzLnQgPSB0aGlzLngucmVkTXVsKHRoaXMueSk7XG4gICAgICBpZiAoIXRoaXMuek9uZSlcbiAgICAgICAgdGhpcy50ID0gdGhpcy50LnJlZE11bCh0aGlzLnoucmVkSW52bSgpKTtcbiAgICB9XG4gIH1cbn1cbmluaGVyaXRzKFBvaW50LCBCYXNlLkJhc2VQb2ludCk7XG5cbkVkd2FyZHNDdXJ2ZS5wcm90b3R5cGUucG9pbnRGcm9tSlNPTiA9IGZ1bmN0aW9uIHBvaW50RnJvbUpTT04ob2JqKSB7XG4gIHJldHVybiBQb2ludC5mcm9tSlNPTih0aGlzLCBvYmopO1xufTtcblxuRWR3YXJkc0N1cnZlLnByb3RvdHlwZS5wb2ludCA9IGZ1bmN0aW9uIHBvaW50KHgsIHksIHosIHQpIHtcbiAgcmV0dXJuIG5ldyBQb2ludCh0aGlzLCB4LCB5LCB6LCB0KTtcbn07XG5cblBvaW50LmZyb21KU09OID0gZnVuY3Rpb24gZnJvbUpTT04oY3VydmUsIG9iaikge1xuICByZXR1cm4gbmV3IFBvaW50KGN1cnZlLCBvYmpbMF0sIG9ialsxXSwgb2JqWzJdKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiAnPEVDIFBvaW50IEluZmluaXR5Pic7XG4gIHJldHVybiAnPEVDIFBvaW50IHg6ICcgKyB0aGlzLnguZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArXG4gICAgICAnIHk6ICcgKyB0aGlzLnkuZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArXG4gICAgICAnIHo6ICcgKyB0aGlzLnouZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArICc+Jztcbn07XG5cblBvaW50LnByb3RvdHlwZS5pc0luZmluaXR5ID0gZnVuY3Rpb24gaXNJbmZpbml0eSgpIHtcbiAgLy8gWFhYIFRoaXMgY29kZSBhc3N1bWVzIHRoYXQgemVybyBpcyBhbHdheXMgemVybyBpbiByZWRcbiAgcmV0dXJuIHRoaXMueC5jbXBuKDApID09PSAwICYmXG4gICAgICAgICB0aGlzLnkuY21wKHRoaXMueikgPT09IDA7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuX2V4dERibCA9IGZ1bmN0aW9uIF9leHREYmwoKSB7XG4gIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by10d2lzdGVkLWV4dGVuZGVkLTEuaHRtbFxuICAvLyAgICAgI2RvdWJsaW5nLWRibC0yMDA4LWh3Y2RcbiAgLy8gNE0gKyA0U1xuXG4gIC8vIEEgPSBYMV4yXG4gIHZhciBhID0gdGhpcy54LnJlZFNxcigpO1xuICAvLyBCID0gWTFeMlxuICB2YXIgYiA9IHRoaXMueS5yZWRTcXIoKTtcbiAgLy8gQyA9IDIgKiBaMV4yXG4gIHZhciBjID0gdGhpcy56LnJlZFNxcigpO1xuICBjID0gYy5yZWRJQWRkKGMpO1xuICAvLyBEID0gYSAqIEFcbiAgdmFyIGQgPSB0aGlzLmN1cnZlLl9tdWxBKGEpO1xuICAvLyBFID0gKFgxICsgWTEpXjIgLSBBIC0gQlxuICB2YXIgZSA9IHRoaXMueC5yZWRBZGQodGhpcy55KS5yZWRTcXIoKS5yZWRJU3ViKGEpLnJlZElTdWIoYik7XG4gIC8vIEcgPSBEICsgQlxuICB2YXIgZyA9IGQucmVkQWRkKGIpO1xuICAvLyBGID0gRyAtIENcbiAgdmFyIGYgPSBnLnJlZFN1YihjKTtcbiAgLy8gSCA9IEQgLSBCXG4gIHZhciBoID0gZC5yZWRTdWIoYik7XG4gIC8vIFgzID0gRSAqIEZcbiAgdmFyIG54ID0gZS5yZWRNdWwoZik7XG4gIC8vIFkzID0gRyAqIEhcbiAgdmFyIG55ID0gZy5yZWRNdWwoaCk7XG4gIC8vIFQzID0gRSAqIEhcbiAgdmFyIG50ID0gZS5yZWRNdWwoaCk7XG4gIC8vIFozID0gRiAqIEdcbiAgdmFyIG56ID0gZi5yZWRNdWwoZyk7XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG54LCBueSwgbnosIG50KTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5fcHJvakRibCA9IGZ1bmN0aW9uIF9wcm9qRGJsKCkge1xuICAvLyBoeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tdHdpc3RlZC1wcm9qZWN0aXZlLmh0bWxcbiAgLy8gICAgICNkb3VibGluZy1kYmwtMjAwOC1iYmpscFxuICAvLyAgICAgI2RvdWJsaW5nLWRibC0yMDA3LWJsXG4gIC8vIGFuZCBvdGhlcnNcbiAgLy8gR2VuZXJhbGx5IDNNICsgNFMgb3IgMk0gKyA0U1xuXG4gIC8vIEIgPSAoWDEgKyBZMSleMlxuICB2YXIgYiA9IHRoaXMueC5yZWRBZGQodGhpcy55KS5yZWRTcXIoKTtcbiAgLy8gQyA9IFgxXjJcbiAgdmFyIGMgPSB0aGlzLngucmVkU3FyKCk7XG4gIC8vIEQgPSBZMV4yXG4gIHZhciBkID0gdGhpcy55LnJlZFNxcigpO1xuXG4gIHZhciBueDtcbiAgdmFyIG55O1xuICB2YXIgbno7XG4gIGlmICh0aGlzLmN1cnZlLnR3aXN0ZWQpIHtcbiAgICAvLyBFID0gYSAqIENcbiAgICB2YXIgZSA9IHRoaXMuY3VydmUuX211bEEoYyk7XG4gICAgLy8gRiA9IEUgKyBEXG4gICAgdmFyIGYgPSBlLnJlZEFkZChkKTtcbiAgICBpZiAodGhpcy56T25lKSB7XG4gICAgICAvLyBYMyA9IChCIC0gQyAtIEQpICogKEYgLSAyKVxuICAgICAgbnggPSBiLnJlZFN1YihjKS5yZWRTdWIoZCkucmVkTXVsKGYucmVkU3ViKHRoaXMuY3VydmUudHdvKSk7XG4gICAgICAvLyBZMyA9IEYgKiAoRSAtIEQpXG4gICAgICBueSA9IGYucmVkTXVsKGUucmVkU3ViKGQpKTtcbiAgICAgIC8vIFozID0gRl4yIC0gMiAqIEZcbiAgICAgIG56ID0gZi5yZWRTcXIoKS5yZWRTdWIoZikucmVkU3ViKGYpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBIID0gWjFeMlxuICAgICAgdmFyIGggPSB0aGlzLnoucmVkU3FyKCk7XG4gICAgICAvLyBKID0gRiAtIDIgKiBIXG4gICAgICB2YXIgaiA9IGYucmVkU3ViKGgpLnJlZElTdWIoaCk7XG4gICAgICAvLyBYMyA9IChCLUMtRCkqSlxuICAgICAgbnggPSBiLnJlZFN1YihjKS5yZWRJU3ViKGQpLnJlZE11bChqKTtcbiAgICAgIC8vIFkzID0gRiAqIChFIC0gRClcbiAgICAgIG55ID0gZi5yZWRNdWwoZS5yZWRTdWIoZCkpO1xuICAgICAgLy8gWjMgPSBGICogSlxuICAgICAgbnogPSBmLnJlZE11bChqKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gRSA9IEMgKyBEXG4gICAgdmFyIGUgPSBjLnJlZEFkZChkKTtcbiAgICAvLyBIID0gKGMgKiBaMSleMlxuICAgIHZhciBoID0gdGhpcy5jdXJ2ZS5fbXVsQyh0aGlzLmMucmVkTXVsKHRoaXMueikpLnJlZFNxcigpO1xuICAgIC8vIEogPSBFIC0gMiAqIEhcbiAgICB2YXIgaiA9IGUucmVkU3ViKGgpLnJlZFN1YihoKTtcbiAgICAvLyBYMyA9IGMgKiAoQiAtIEUpICogSlxuICAgIG54ID0gdGhpcy5jdXJ2ZS5fbXVsQyhiLnJlZElTdWIoZSkpLnJlZE11bChqKTtcbiAgICAvLyBZMyA9IGMgKiBFICogKEMgLSBEKVxuICAgIG55ID0gdGhpcy5jdXJ2ZS5fbXVsQyhlKS5yZWRNdWwoYy5yZWRJU3ViKGQpKTtcbiAgICAvLyBaMyA9IEUgKiBKXG4gICAgbnogPSBlLnJlZE11bChqKTtcbiAgfVxuICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChueCwgbnksIG56KTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5kYmwgPSBmdW5jdGlvbiBkYmwoKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBEb3VibGUgaW4gZXh0ZW5kZWQgY29vcmRpbmF0ZXNcbiAgaWYgKHRoaXMuY3VydmUuZXh0ZW5kZWQpXG4gICAgcmV0dXJuIHRoaXMuX2V4dERibCgpO1xuICBlbHNlXG4gICAgcmV0dXJuIHRoaXMuX3Byb2pEYmwoKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5fZXh0QWRkID0gZnVuY3Rpb24gX2V4dEFkZChwKSB7XG4gIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by10d2lzdGVkLWV4dGVuZGVkLTEuaHRtbFxuICAvLyAgICAgI2FkZGl0aW9uLWFkZC0yMDA4LWh3Y2QtM1xuICAvLyA4TVxuXG4gIC8vIEEgPSAoWTEgLSBYMSkgKiAoWTIgLSBYMilcbiAgdmFyIGEgPSB0aGlzLnkucmVkU3ViKHRoaXMueCkucmVkTXVsKHAueS5yZWRTdWIocC54KSk7XG4gIC8vIEIgPSAoWTEgKyBYMSkgKiAoWTIgKyBYMilcbiAgdmFyIGIgPSB0aGlzLnkucmVkQWRkKHRoaXMueCkucmVkTXVsKHAueS5yZWRBZGQocC54KSk7XG4gIC8vIEMgPSBUMSAqIGsgKiBUMlxuICB2YXIgYyA9IHRoaXMudC5yZWRNdWwodGhpcy5jdXJ2ZS5kZCkucmVkTXVsKHAudCk7XG4gIC8vIEQgPSBaMSAqIDIgKiBaMlxuICB2YXIgZCA9IHRoaXMuei5yZWRNdWwocC56LnJlZEFkZChwLnopKTtcbiAgLy8gRSA9IEIgLSBBXG4gIHZhciBlID0gYi5yZWRTdWIoYSk7XG4gIC8vIEYgPSBEIC0gQ1xuICB2YXIgZiA9IGQucmVkU3ViKGMpO1xuICAvLyBHID0gRCArIENcbiAgdmFyIGcgPSBkLnJlZEFkZChjKTtcbiAgLy8gSCA9IEIgKyBBXG4gIHZhciBoID0gYi5yZWRBZGQoYSk7XG4gIC8vIFgzID0gRSAqIEZcbiAgdmFyIG54ID0gZS5yZWRNdWwoZik7XG4gIC8vIFkzID0gRyAqIEhcbiAgdmFyIG55ID0gZy5yZWRNdWwoaCk7XG4gIC8vIFQzID0gRSAqIEhcbiAgdmFyIG50ID0gZS5yZWRNdWwoaCk7XG4gIC8vIFozID0gRiAqIEdcbiAgdmFyIG56ID0gZi5yZWRNdWwoZyk7XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG54LCBueSwgbnosIG50KTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5fcHJvakFkZCA9IGZ1bmN0aW9uIF9wcm9qQWRkKHApIHtcbiAgLy8gaHlwZXJlbGxpcHRpYy5vcmcvRUZEL2cxcC9hdXRvLXR3aXN0ZWQtcHJvamVjdGl2ZS5odG1sXG4gIC8vICAgICAjYWRkaXRpb24tYWRkLTIwMDgtYmJqbHBcbiAgLy8gICAgICNhZGRpdGlvbi1hZGQtMjAwNy1ibFxuICAvLyAxME0gKyAxU1xuXG4gIC8vIEEgPSBaMSAqIFoyXG4gIHZhciBhID0gdGhpcy56LnJlZE11bChwLnopO1xuICAvLyBCID0gQV4yXG4gIHZhciBiID0gYS5yZWRTcXIoKTtcbiAgLy8gQyA9IFgxICogWDJcbiAgdmFyIGMgPSB0aGlzLngucmVkTXVsKHAueCk7XG4gIC8vIEQgPSBZMSAqIFkyXG4gIHZhciBkID0gdGhpcy55LnJlZE11bChwLnkpO1xuICAvLyBFID0gZCAqIEMgKiBEXG4gIHZhciBlID0gdGhpcy5jdXJ2ZS5kLnJlZE11bChjKS5yZWRNdWwoZCk7XG4gIC8vIEYgPSBCIC0gRVxuICB2YXIgZiA9IGIucmVkU3ViKGUpO1xuICAvLyBHID0gQiArIEVcbiAgdmFyIGcgPSBiLnJlZEFkZChlKTtcbiAgLy8gWDMgPSBBICogRiAqICgoWDEgKyBZMSkgKiAoWDIgKyBZMikgLSBDIC0gRClcbiAgdmFyIHRtcCA9IHRoaXMueC5yZWRBZGQodGhpcy55KS5yZWRNdWwocC54LnJlZEFkZChwLnkpKS5yZWRJU3ViKGMpLnJlZElTdWIoZCk7XG4gIHZhciBueCA9IGEucmVkTXVsKGYpLnJlZE11bCh0bXApO1xuICB2YXIgbnk7XG4gIHZhciBuejtcbiAgaWYgKHRoaXMuY3VydmUudHdpc3RlZCkge1xuICAgIC8vIFkzID0gQSAqIEcgKiAoRCAtIGEgKiBDKVxuICAgIG55ID0gYS5yZWRNdWwoZykucmVkTXVsKGQucmVkU3ViKHRoaXMuY3VydmUuX211bEEoYykpKTtcbiAgICAvLyBaMyA9IEYgKiBHXG4gICAgbnogPSBmLnJlZE11bChnKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBZMyA9IEEgKiBHICogKEQgLSBDKVxuICAgIG55ID0gYS5yZWRNdWwoZykucmVkTXVsKGQucmVkU3ViKGMpKTtcbiAgICAvLyBaMyA9IGMgKiBGICogR1xuICAgIG56ID0gdGhpcy5jdXJ2ZS5fbXVsQyhmKS5yZWRNdWwoZyk7XG4gIH1cbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobngsIG55LCBueik7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gYWRkKHApIHtcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiBwO1xuICBpZiAocC5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgaWYgKHRoaXMuY3VydmUuZXh0ZW5kZWQpXG4gICAgcmV0dXJuIHRoaXMuX2V4dEFkZChwKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLl9wcm9qQWRkKHApO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm11bCA9IGZ1bmN0aW9uIG11bChrKSB7XG4gIGlmICh0aGlzLl9oYXNEb3VibGVzKGspKVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl9maXhlZE5hZk11bCh0aGlzLCBrKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl93bmFmTXVsKHRoaXMsIGspO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm11bEFkZCA9IGZ1bmN0aW9uIG11bEFkZChrMSwgcCwgazIpIHtcbiAgcmV0dXJuIHRoaXMuY3VydmUuX3duYWZNdWxBZGQoMSwgWyB0aGlzLCBwIF0sIFsgazEsIGsyIF0sIDIpO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm5vcm1hbGl6ZSA9IGZ1bmN0aW9uIG5vcm1hbGl6ZSgpIHtcbiAgaWYgKHRoaXMuek9uZSlcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBOb3JtYWxpemUgY29vcmRpbmF0ZXNcbiAgdmFyIHppID0gdGhpcy56LnJlZEludm0oKTtcbiAgdGhpcy54ID0gdGhpcy54LnJlZE11bCh6aSk7XG4gIHRoaXMueSA9IHRoaXMueS5yZWRNdWwoemkpO1xuICBpZiAodGhpcy50KVxuICAgIHRoaXMudCA9IHRoaXMudC5yZWRNdWwoemkpO1xuICB0aGlzLnogPSB0aGlzLmN1cnZlLm9uZTtcbiAgdGhpcy56T25lID0gdHJ1ZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUubmVnID0gZnVuY3Rpb24gbmVnKCkge1xuICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludCh0aGlzLngucmVkTmVnKCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMueSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy56LFxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnQgJiYgdGhpcy50LnJlZE5lZygpKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5nZXRYID0gZnVuY3Rpb24gZ2V0WCgpIHtcbiAgdGhpcy5ub3JtYWxpemUoKTtcbiAgcmV0dXJuIHRoaXMueC5mcm9tUmVkKCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZ2V0WSA9IGZ1bmN0aW9uIGdldFkoKSB7XG4gIHRoaXMubm9ybWFsaXplKCk7XG4gIHJldHVybiB0aGlzLnkuZnJvbVJlZCgpO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmVxID0gZnVuY3Rpb24gZXEob3RoZXIpIHtcbiAgcmV0dXJuIHRoaXMgPT09IG90aGVyIHx8XG4gICAgICAgICB0aGlzLmdldFgoKS5jbXAob3RoZXIuZ2V0WCgpKSA9PT0gMCAmJlxuICAgICAgICAgdGhpcy5nZXRZKCkuY21wKG90aGVyLmdldFkoKSkgPT09IDA7XG59O1xuXG4vLyBDb21wYXRpYmlsaXR5IHdpdGggQmFzZUN1cnZlXG5Qb2ludC5wcm90b3R5cGUudG9QID0gUG9pbnQucHJvdG90eXBlLm5vcm1hbGl6ZTtcblBvaW50LnByb3RvdHlwZS5taXhlZEFkZCA9IFBvaW50LnByb3RvdHlwZS5hZGQ7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBjdXJ2ZSA9IGV4cG9ydHM7XG5cbmN1cnZlLmJhc2UgPSByZXF1aXJlKCcuL2Jhc2UnKTtcbmN1cnZlLnNob3J0ID0gcmVxdWlyZSgnLi9zaG9ydCcpO1xuY3VydmUubW9udCA9IHJlcXVpcmUoJy4vbW9udCcpO1xuY3VydmUuZWR3YXJkcyA9IHJlcXVpcmUoJy4vZWR3YXJkcycpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3VydmUgPSByZXF1aXJlKCcuLi9jdXJ2ZScpO1xudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG52YXIgQmFzZSA9IGN1cnZlLmJhc2U7XG5cbnZhciBlbGxpcHRpYyA9IHJlcXVpcmUoJy4uLy4uL2VsbGlwdGljJyk7XG52YXIgdXRpbHMgPSBlbGxpcHRpYy51dGlscztcblxuZnVuY3Rpb24gTW9udEN1cnZlKGNvbmYpIHtcbiAgQmFzZS5jYWxsKHRoaXMsICdtb250JywgY29uZik7XG5cbiAgdGhpcy5hID0gbmV3IEJOKGNvbmYuYSwgMTYpLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5iID0gbmV3IEJOKGNvbmYuYiwgMTYpLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5pNCA9IG5ldyBCTig0KS50b1JlZCh0aGlzLnJlZCkucmVkSW52bSgpO1xuICB0aGlzLnR3byA9IG5ldyBCTigyKS50b1JlZCh0aGlzLnJlZCk7XG4gIHRoaXMuYTI0ID0gdGhpcy5pNC5yZWRNdWwodGhpcy5hLnJlZEFkZCh0aGlzLnR3bykpO1xufVxuaW5oZXJpdHMoTW9udEN1cnZlLCBCYXNlKTtcbm1vZHVsZS5leHBvcnRzID0gTW9udEN1cnZlO1xuXG5Nb250Q3VydmUucHJvdG90eXBlLnZhbGlkYXRlID0gZnVuY3Rpb24gdmFsaWRhdGUocG9pbnQpIHtcbiAgdmFyIHggPSBwb2ludC5ub3JtYWxpemUoKS54O1xuICB2YXIgeDIgPSB4LnJlZFNxcigpO1xuICB2YXIgcmhzID0geDIucmVkTXVsKHgpLnJlZEFkZCh4Mi5yZWRNdWwodGhpcy5hKSkucmVkQWRkKHgpO1xuICB2YXIgeSA9IHJocy5yZWRTcXJ0KCk7XG5cbiAgcmV0dXJuIHkucmVkU3FyKCkuY21wKHJocykgPT09IDA7XG59O1xuXG5mdW5jdGlvbiBQb2ludChjdXJ2ZSwgeCwgeikge1xuICBCYXNlLkJhc2VQb2ludC5jYWxsKHRoaXMsIGN1cnZlLCAncHJvamVjdGl2ZScpO1xuICBpZiAoeCA9PT0gbnVsbCAmJiB6ID09PSBudWxsKSB7XG4gICAgdGhpcy54ID0gdGhpcy5jdXJ2ZS5vbmU7XG4gICAgdGhpcy56ID0gdGhpcy5jdXJ2ZS56ZXJvO1xuICB9IGVsc2Uge1xuICAgIHRoaXMueCA9IG5ldyBCTih4LCAxNik7XG4gICAgdGhpcy56ID0gbmV3IEJOKHosIDE2KTtcbiAgICBpZiAoIXRoaXMueC5yZWQpXG4gICAgICB0aGlzLnggPSB0aGlzLngudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICAgIGlmICghdGhpcy56LnJlZClcbiAgICAgIHRoaXMueiA9IHRoaXMuei50b1JlZCh0aGlzLmN1cnZlLnJlZCk7XG4gIH1cbn1cbmluaGVyaXRzKFBvaW50LCBCYXNlLkJhc2VQb2ludCk7XG5cbk1vbnRDdXJ2ZS5wcm90b3R5cGUuZGVjb2RlUG9pbnQgPSBmdW5jdGlvbiBkZWNvZGVQb2ludChieXRlcywgZW5jKSB7XG4gIHJldHVybiB0aGlzLnBvaW50KHV0aWxzLnRvQXJyYXkoYnl0ZXMsIGVuYyksIDEpO1xufTtcblxuTW9udEN1cnZlLnByb3RvdHlwZS5wb2ludCA9IGZ1bmN0aW9uIHBvaW50KHgsIHopIHtcbiAgcmV0dXJuIG5ldyBQb2ludCh0aGlzLCB4LCB6KTtcbn07XG5cbk1vbnRDdXJ2ZS5wcm90b3R5cGUucG9pbnRGcm9tSlNPTiA9IGZ1bmN0aW9uIHBvaW50RnJvbUpTT04ob2JqKSB7XG4gIHJldHVybiBQb2ludC5mcm9tSlNPTih0aGlzLCBvYmopO1xufTtcblxuUG9pbnQucHJvdG90eXBlLnByZWNvbXB1dGUgPSBmdW5jdGlvbiBwcmVjb21wdXRlKCkge1xuICAvLyBOby1vcFxufTtcblxuUG9pbnQucHJvdG90eXBlLl9lbmNvZGUgPSBmdW5jdGlvbiBfZW5jb2RlKCkge1xuICByZXR1cm4gdGhpcy5nZXRYKCkudG9BcnJheSgnYmUnLCB0aGlzLmN1cnZlLnAuYnl0ZUxlbmd0aCgpKTtcbn07XG5cblBvaW50LmZyb21KU09OID0gZnVuY3Rpb24gZnJvbUpTT04oY3VydmUsIG9iaikge1xuICByZXR1cm4gbmV3IFBvaW50KGN1cnZlLCBvYmpbMF0sIG9ialsxXSB8fCBjdXJ2ZS5vbmUpO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0KCkge1xuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuICc8RUMgUG9pbnQgSW5maW5pdHk+JztcbiAgcmV0dXJuICc8RUMgUG9pbnQgeDogJyArIHRoaXMueC5mcm9tUmVkKCkudG9TdHJpbmcoMTYsIDIpICtcbiAgICAgICcgejogJyArIHRoaXMuei5mcm9tUmVkKCkudG9TdHJpbmcoMTYsIDIpICsgJz4nO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmlzSW5maW5pdHkgPSBmdW5jdGlvbiBpc0luZmluaXR5KCkge1xuICAvLyBYWFggVGhpcyBjb2RlIGFzc3VtZXMgdGhhdCB6ZXJvIGlzIGFsd2F5cyB6ZXJvIGluIHJlZFxuICByZXR1cm4gdGhpcy56LmNtcG4oMCkgPT09IDA7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZGJsID0gZnVuY3Rpb24gZGJsKCkge1xuICAvLyBodHRwOi8vaHlwZXJlbGxpcHRpYy5vcmcvRUZEL2cxcC9hdXRvLW1vbnRnb20teHouaHRtbCNkb3VibGluZy1kYmwtMTk4Ny1tLTNcbiAgLy8gMk0gKyAyUyArIDRBXG5cbiAgLy8gQSA9IFgxICsgWjFcbiAgdmFyIGEgPSB0aGlzLngucmVkQWRkKHRoaXMueik7XG4gIC8vIEFBID0gQV4yXG4gIHZhciBhYSA9IGEucmVkU3FyKCk7XG4gIC8vIEIgPSBYMSAtIFoxXG4gIHZhciBiID0gdGhpcy54LnJlZFN1Yih0aGlzLnopO1xuICAvLyBCQiA9IEJeMlxuICB2YXIgYmIgPSBiLnJlZFNxcigpO1xuICAvLyBDID0gQUEgLSBCQlxuICB2YXIgYyA9IGFhLnJlZFN1YihiYik7XG4gIC8vIFgzID0gQUEgKiBCQlxuICB2YXIgbnggPSBhYS5yZWRNdWwoYmIpO1xuICAvLyBaMyA9IEMgKiAoQkIgKyBBMjQgKiBDKVxuICB2YXIgbnogPSBjLnJlZE11bChiYi5yZWRBZGQodGhpcy5jdXJ2ZS5hMjQucmVkTXVsKGMpKSk7XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG54LCBueik7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gYWRkKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBzdXBwb3J0ZWQgb24gTW9udGdvbWVyeSBjdXJ2ZScpO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmRpZmZBZGQgPSBmdW5jdGlvbiBkaWZmQWRkKHAsIGRpZmYpIHtcbiAgLy8gaHR0cDovL2h5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by1tb250Z29tLXh6Lmh0bWwjZGlmZmFkZC1kYWRkLTE5ODctbS0zXG4gIC8vIDRNICsgMlMgKyA2QVxuXG4gIC8vIEEgPSBYMiArIFoyXG4gIHZhciBhID0gdGhpcy54LnJlZEFkZCh0aGlzLnopO1xuICAvLyBCID0gWDIgLSBaMlxuICB2YXIgYiA9IHRoaXMueC5yZWRTdWIodGhpcy56KTtcbiAgLy8gQyA9IFgzICsgWjNcbiAgdmFyIGMgPSBwLngucmVkQWRkKHAueik7XG4gIC8vIEQgPSBYMyAtIFozXG4gIHZhciBkID0gcC54LnJlZFN1YihwLnopO1xuICAvLyBEQSA9IEQgKiBBXG4gIHZhciBkYSA9IGQucmVkTXVsKGEpO1xuICAvLyBDQiA9IEMgKiBCXG4gIHZhciBjYiA9IGMucmVkTXVsKGIpO1xuICAvLyBYNSA9IFoxICogKERBICsgQ0IpXjJcbiAgdmFyIG54ID0gZGlmZi56LnJlZE11bChkYS5yZWRBZGQoY2IpLnJlZFNxcigpKTtcbiAgLy8gWjUgPSBYMSAqIChEQSAtIENCKV4yXG4gIHZhciBueiA9IGRpZmYueC5yZWRNdWwoZGEucmVkSVN1YihjYikucmVkU3FyKCkpO1xuICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChueCwgbnopO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm11bCA9IGZ1bmN0aW9uIG11bChrKSB7XG4gIHZhciB0ID0gay5jbG9uZSgpO1xuICB2YXIgYSA9IHRoaXM7IC8vIChOIC8gMikgKiBRICsgUVxuICB2YXIgYiA9IHRoaXMuY3VydmUucG9pbnQobnVsbCwgbnVsbCk7IC8vIChOIC8gMikgKiBRXG4gIHZhciBjID0gdGhpczsgLy8gUVxuXG4gIGZvciAodmFyIGJpdHMgPSBbXTsgdC5jbXBuKDApICE9PSAwOyB0Lml1c2hybigxKSlcbiAgICBiaXRzLnB1c2godC5hbmRsbigxKSk7XG5cbiAgZm9yICh2YXIgaSA9IGJpdHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBpZiAoYml0c1tpXSA9PT0gMCkge1xuICAgICAgLy8gTiAqIFEgKyBRID0gKChOIC8gMikgKiBRICsgUSkpICsgKE4gLyAyKSAqIFFcbiAgICAgIGEgPSBhLmRpZmZBZGQoYiwgYyk7XG4gICAgICAvLyBOICogUSA9IDIgKiAoKE4gLyAyKSAqIFEgKyBRKSlcbiAgICAgIGIgPSBiLmRibCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBOICogUSA9ICgoTiAvIDIpICogUSArIFEpICsgKChOIC8gMikgKiBRKVxuICAgICAgYiA9IGEuZGlmZkFkZChiLCBjKTtcbiAgICAgIC8vIE4gKiBRICsgUSA9IDIgKiAoKE4gLyAyKSAqIFEgKyBRKVxuICAgICAgYSA9IGEuZGJsKCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBiO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm11bEFkZCA9IGZ1bmN0aW9uIG11bEFkZCgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdOb3Qgc3VwcG9ydGVkIG9uIE1vbnRnb21lcnkgY3VydmUnKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5lcSA9IGZ1bmN0aW9uIGVxKG90aGVyKSB7XG4gIHJldHVybiB0aGlzLmdldFgoKS5jbXAob3RoZXIuZ2V0WCgpKSA9PT0gMDtcbn07XG5cblBvaW50LnByb3RvdHlwZS5ub3JtYWxpemUgPSBmdW5jdGlvbiBub3JtYWxpemUoKSB7XG4gIHRoaXMueCA9IHRoaXMueC5yZWRNdWwodGhpcy56LnJlZEludm0oKSk7XG4gIHRoaXMueiA9IHRoaXMuY3VydmUub25lO1xuICByZXR1cm4gdGhpcztcbn07XG5cblBvaW50LnByb3RvdHlwZS5nZXRYID0gZnVuY3Rpb24gZ2V0WCgpIHtcbiAgLy8gTm9ybWFsaXplIGNvb3JkaW5hdGVzXG4gIHRoaXMubm9ybWFsaXplKCk7XG5cbiAgcmV0dXJuIHRoaXMueC5mcm9tUmVkKCk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3VydmUgPSByZXF1aXJlKCcuLi9jdXJ2ZScpO1xudmFyIGVsbGlwdGljID0gcmVxdWlyZSgnLi4vLi4vZWxsaXB0aWMnKTtcbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xudmFyIEJhc2UgPSBjdXJ2ZS5iYXNlO1xuXG52YXIgYXNzZXJ0ID0gZWxsaXB0aWMudXRpbHMuYXNzZXJ0O1xuXG5mdW5jdGlvbiBTaG9ydEN1cnZlKGNvbmYpIHtcbiAgQmFzZS5jYWxsKHRoaXMsICdzaG9ydCcsIGNvbmYpO1xuXG4gIHRoaXMuYSA9IG5ldyBCTihjb25mLmEsIDE2KS50b1JlZCh0aGlzLnJlZCk7XG4gIHRoaXMuYiA9IG5ldyBCTihjb25mLmIsIDE2KS50b1JlZCh0aGlzLnJlZCk7XG4gIHRoaXMudGludiA9IHRoaXMudHdvLnJlZEludm0oKTtcblxuICB0aGlzLnplcm9BID0gdGhpcy5hLmZyb21SZWQoKS5jbXBuKDApID09PSAwO1xuICB0aGlzLnRocmVlQSA9IHRoaXMuYS5mcm9tUmVkKCkuc3ViKHRoaXMucCkuY21wbigtMykgPT09IDA7XG5cbiAgLy8gSWYgdGhlIGN1cnZlIGlzIGVuZG9tb3JwaGljLCBwcmVjYWxjdWxhdGUgYmV0YSBhbmQgbGFtYmRhXG4gIHRoaXMuZW5kbyA9IHRoaXMuX2dldEVuZG9tb3JwaGlzbShjb25mKTtcbiAgdGhpcy5fZW5kb1duYWZUMSA9IG5ldyBBcnJheSg0KTtcbiAgdGhpcy5fZW5kb1duYWZUMiA9IG5ldyBBcnJheSg0KTtcbn1cbmluaGVyaXRzKFNob3J0Q3VydmUsIEJhc2UpO1xubW9kdWxlLmV4cG9ydHMgPSBTaG9ydEN1cnZlO1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS5fZ2V0RW5kb21vcnBoaXNtID0gZnVuY3Rpb24gX2dldEVuZG9tb3JwaGlzbShjb25mKSB7XG4gIC8vIE5vIGVmZmljaWVudCBlbmRvbW9ycGhpc21cbiAgaWYgKCF0aGlzLnplcm9BIHx8ICF0aGlzLmcgfHwgIXRoaXMubiB8fCB0aGlzLnAubW9kbigzKSAhPT0gMSlcbiAgICByZXR1cm47XG5cbiAgLy8gQ29tcHV0ZSBiZXRhIGFuZCBsYW1iZGEsIHRoYXQgbGFtYmRhICogUCA9IChiZXRhICogUHg7IFB5KVxuICB2YXIgYmV0YTtcbiAgdmFyIGxhbWJkYTtcbiAgaWYgKGNvbmYuYmV0YSkge1xuICAgIGJldGEgPSBuZXcgQk4oY29uZi5iZXRhLCAxNikudG9SZWQodGhpcy5yZWQpO1xuICB9IGVsc2Uge1xuICAgIHZhciBiZXRhcyA9IHRoaXMuX2dldEVuZG9Sb290cyh0aGlzLnApO1xuICAgIC8vIENob29zZSB0aGUgc21hbGxlc3QgYmV0YVxuICAgIGJldGEgPSBiZXRhc1swXS5jbXAoYmV0YXNbMV0pIDwgMCA/IGJldGFzWzBdIDogYmV0YXNbMV07XG4gICAgYmV0YSA9IGJldGEudG9SZWQodGhpcy5yZWQpO1xuICB9XG4gIGlmIChjb25mLmxhbWJkYSkge1xuICAgIGxhbWJkYSA9IG5ldyBCTihjb25mLmxhbWJkYSwgMTYpO1xuICB9IGVsc2Uge1xuICAgIC8vIENob29zZSB0aGUgbGFtYmRhIHRoYXQgaXMgbWF0Y2hpbmcgc2VsZWN0ZWQgYmV0YVxuICAgIHZhciBsYW1iZGFzID0gdGhpcy5fZ2V0RW5kb1Jvb3RzKHRoaXMubik7XG4gICAgaWYgKHRoaXMuZy5tdWwobGFtYmRhc1swXSkueC5jbXAodGhpcy5nLngucmVkTXVsKGJldGEpKSA9PT0gMCkge1xuICAgICAgbGFtYmRhID0gbGFtYmRhc1swXTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGFtYmRhID0gbGFtYmRhc1sxXTtcbiAgICAgIGFzc2VydCh0aGlzLmcubXVsKGxhbWJkYSkueC5jbXAodGhpcy5nLngucmVkTXVsKGJldGEpKSA9PT0gMCk7XG4gICAgfVxuICB9XG5cbiAgLy8gR2V0IGJhc2lzIHZlY3RvcnMsIHVzZWQgZm9yIGJhbGFuY2VkIGxlbmd0aC10d28gcmVwcmVzZW50YXRpb25cbiAgdmFyIGJhc2lzO1xuICBpZiAoY29uZi5iYXNpcykge1xuICAgIGJhc2lzID0gY29uZi5iYXNpcy5tYXAoZnVuY3Rpb24odmVjKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBhOiBuZXcgQk4odmVjLmEsIDE2KSxcbiAgICAgICAgYjogbmV3IEJOKHZlYy5iLCAxNilcbiAgICAgIH07XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgYmFzaXMgPSB0aGlzLl9nZXRFbmRvQmFzaXMobGFtYmRhKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgYmV0YTogYmV0YSxcbiAgICBsYW1iZGE6IGxhbWJkYSxcbiAgICBiYXNpczogYmFzaXNcbiAgfTtcbn07XG5cblNob3J0Q3VydmUucHJvdG90eXBlLl9nZXRFbmRvUm9vdHMgPSBmdW5jdGlvbiBfZ2V0RW5kb1Jvb3RzKG51bSkge1xuICAvLyBGaW5kIHJvb3RzIG9mIGZvciB4XjIgKyB4ICsgMSBpbiBGXG4gIC8vIFJvb3QgPSAoLTEgKy0gU3FydCgtMykpIC8gMlxuICAvL1xuICB2YXIgcmVkID0gbnVtID09PSB0aGlzLnAgPyB0aGlzLnJlZCA6IEJOLm1vbnQobnVtKTtcbiAgdmFyIHRpbnYgPSBuZXcgQk4oMikudG9SZWQocmVkKS5yZWRJbnZtKCk7XG4gIHZhciBudGludiA9IHRpbnYucmVkTmVnKCk7XG5cbiAgdmFyIHMgPSBuZXcgQk4oMykudG9SZWQocmVkKS5yZWROZWcoKS5yZWRTcXJ0KCkucmVkTXVsKHRpbnYpO1xuXG4gIHZhciBsMSA9IG50aW52LnJlZEFkZChzKS5mcm9tUmVkKCk7XG4gIHZhciBsMiA9IG50aW52LnJlZFN1YihzKS5mcm9tUmVkKCk7XG4gIHJldHVybiBbIGwxLCBsMiBdO1xufTtcblxuU2hvcnRDdXJ2ZS5wcm90b3R5cGUuX2dldEVuZG9CYXNpcyA9IGZ1bmN0aW9uIF9nZXRFbmRvQmFzaXMobGFtYmRhKSB7XG4gIC8vIGFwcnhTcXJ0ID49IHNxcnQodGhpcy5uKVxuICB2YXIgYXByeFNxcnQgPSB0aGlzLm4udXNocm4oTWF0aC5mbG9vcih0aGlzLm4uYml0TGVuZ3RoKCkgLyAyKSk7XG5cbiAgLy8gMy43NFxuICAvLyBSdW4gRUdDRCwgdW50aWwgcihMICsgMSkgPCBhcHJ4U3FydFxuICB2YXIgdSA9IGxhbWJkYTtcbiAgdmFyIHYgPSB0aGlzLm4uY2xvbmUoKTtcbiAgdmFyIHgxID0gbmV3IEJOKDEpO1xuICB2YXIgeTEgPSBuZXcgQk4oMCk7XG4gIHZhciB4MiA9IG5ldyBCTigwKTtcbiAgdmFyIHkyID0gbmV3IEJOKDEpO1xuXG4gIC8vIE5PVEU6IGFsbCB2ZWN0b3JzIGFyZSByb290cyBvZjogYSArIGIgKiBsYW1iZGEgPSAwIChtb2QgbilcbiAgdmFyIGEwO1xuICB2YXIgYjA7XG4gIC8vIEZpcnN0IHZlY3RvclxuICB2YXIgYTE7XG4gIHZhciBiMTtcbiAgLy8gU2Vjb25kIHZlY3RvclxuICB2YXIgYTI7XG4gIHZhciBiMjtcblxuICB2YXIgcHJldlI7XG4gIHZhciBpID0gMDtcbiAgdmFyIHI7XG4gIHZhciB4O1xuICB3aGlsZSAodS5jbXBuKDApICE9PSAwKSB7XG4gICAgdmFyIHEgPSB2LmRpdih1KTtcbiAgICByID0gdi5zdWIocS5tdWwodSkpO1xuICAgIHggPSB4Mi5zdWIocS5tdWwoeDEpKTtcbiAgICB2YXIgeSA9IHkyLnN1YihxLm11bCh5MSkpO1xuXG4gICAgaWYgKCFhMSAmJiByLmNtcChhcHJ4U3FydCkgPCAwKSB7XG4gICAgICBhMCA9IHByZXZSLm5lZygpO1xuICAgICAgYjAgPSB4MTtcbiAgICAgIGExID0gci5uZWcoKTtcbiAgICAgIGIxID0geDtcbiAgICB9IGVsc2UgaWYgKGExICYmICsraSA9PT0gMikge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHByZXZSID0gcjtcblxuICAgIHYgPSB1O1xuICAgIHUgPSByO1xuICAgIHgyID0geDE7XG4gICAgeDEgPSB4O1xuICAgIHkyID0geTE7XG4gICAgeTEgPSB5O1xuICB9XG4gIGEyID0gci5uZWcoKTtcbiAgYjIgPSB4O1xuXG4gIHZhciBsZW4xID0gYTEuc3FyKCkuYWRkKGIxLnNxcigpKTtcbiAgdmFyIGxlbjIgPSBhMi5zcXIoKS5hZGQoYjIuc3FyKCkpO1xuICBpZiAobGVuMi5jbXAobGVuMSkgPj0gMCkge1xuICAgIGEyID0gYTA7XG4gICAgYjIgPSBiMDtcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSBzaWduc1xuICBpZiAoYTEubmVnYXRpdmUpIHtcbiAgICBhMSA9IGExLm5lZygpO1xuICAgIGIxID0gYjEubmVnKCk7XG4gIH1cbiAgaWYgKGEyLm5lZ2F0aXZlKSB7XG4gICAgYTIgPSBhMi5uZWcoKTtcbiAgICBiMiA9IGIyLm5lZygpO1xuICB9XG5cbiAgcmV0dXJuIFtcbiAgICB7IGE6IGExLCBiOiBiMSB9LFxuICAgIHsgYTogYTIsIGI6IGIyIH1cbiAgXTtcbn07XG5cblNob3J0Q3VydmUucHJvdG90eXBlLl9lbmRvU3BsaXQgPSBmdW5jdGlvbiBfZW5kb1NwbGl0KGspIHtcbiAgdmFyIGJhc2lzID0gdGhpcy5lbmRvLmJhc2lzO1xuICB2YXIgdjEgPSBiYXNpc1swXTtcbiAgdmFyIHYyID0gYmFzaXNbMV07XG5cbiAgdmFyIGMxID0gdjIuYi5tdWwoaykuZGl2Um91bmQodGhpcy5uKTtcbiAgdmFyIGMyID0gdjEuYi5uZWcoKS5tdWwoaykuZGl2Um91bmQodGhpcy5uKTtcblxuICB2YXIgcDEgPSBjMS5tdWwodjEuYSk7XG4gIHZhciBwMiA9IGMyLm11bCh2Mi5hKTtcbiAgdmFyIHExID0gYzEubXVsKHYxLmIpO1xuICB2YXIgcTIgPSBjMi5tdWwodjIuYik7XG5cbiAgLy8gQ2FsY3VsYXRlIGFuc3dlclxuICB2YXIgazEgPSBrLnN1YihwMSkuc3ViKHAyKTtcbiAgdmFyIGsyID0gcTEuYWRkKHEyKS5uZWcoKTtcbiAgcmV0dXJuIHsgazE6IGsxLCBrMjogazIgfTtcbn07XG5cblNob3J0Q3VydmUucHJvdG90eXBlLnBvaW50RnJvbVggPSBmdW5jdGlvbiBwb2ludEZyb21YKHgsIG9kZCkge1xuICB4ID0gbmV3IEJOKHgsIDE2KTtcbiAgaWYgKCF4LnJlZClcbiAgICB4ID0geC50b1JlZCh0aGlzLnJlZCk7XG5cbiAgdmFyIHkyID0geC5yZWRTcXIoKS5yZWRNdWwoeCkucmVkSUFkZCh4LnJlZE11bCh0aGlzLmEpKS5yZWRJQWRkKHRoaXMuYik7XG4gIHZhciB5ID0geTIucmVkU3FydCgpO1xuICBpZiAoeS5yZWRTcXIoKS5yZWRTdWIoeTIpLmNtcCh0aGlzLnplcm8pICE9PSAwKVxuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBwb2ludCcpO1xuXG4gIC8vIFhYWCBJcyB0aGVyZSBhbnkgd2F5IHRvIHRlbGwgaWYgdGhlIG51bWJlciBpcyBvZGQgd2l0aG91dCBjb252ZXJ0aW5nIGl0XG4gIC8vIHRvIG5vbi1yZWQgZm9ybT9cbiAgdmFyIGlzT2RkID0geS5mcm9tUmVkKCkuaXNPZGQoKTtcbiAgaWYgKG9kZCAmJiAhaXNPZGQgfHwgIW9kZCAmJiBpc09kZClcbiAgICB5ID0geS5yZWROZWcoKTtcblxuICByZXR1cm4gdGhpcy5wb2ludCh4LCB5KTtcbn07XG5cblNob3J0Q3VydmUucHJvdG90eXBlLnZhbGlkYXRlID0gZnVuY3Rpb24gdmFsaWRhdGUocG9pbnQpIHtcbiAgaWYgKHBvaW50LmluZilcbiAgICByZXR1cm4gdHJ1ZTtcblxuICB2YXIgeCA9IHBvaW50Lng7XG4gIHZhciB5ID0gcG9pbnQueTtcblxuICB2YXIgYXggPSB0aGlzLmEucmVkTXVsKHgpO1xuICB2YXIgcmhzID0geC5yZWRTcXIoKS5yZWRNdWwoeCkucmVkSUFkZChheCkucmVkSUFkZCh0aGlzLmIpO1xuICByZXR1cm4geS5yZWRTcXIoKS5yZWRJU3ViKHJocykuY21wbigwKSA9PT0gMDtcbn07XG5cblNob3J0Q3VydmUucHJvdG90eXBlLl9lbmRvV25hZk11bEFkZCA9XG4gICAgZnVuY3Rpb24gX2VuZG9XbmFmTXVsQWRkKHBvaW50cywgY29lZmZzKSB7XG4gIHZhciBucG9pbnRzID0gdGhpcy5fZW5kb1duYWZUMTtcbiAgdmFyIG5jb2VmZnMgPSB0aGlzLl9lbmRvV25hZlQyO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHBvaW50cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBzcGxpdCA9IHRoaXMuX2VuZG9TcGxpdChjb2VmZnNbaV0pO1xuICAgIHZhciBwID0gcG9pbnRzW2ldO1xuICAgIHZhciBiZXRhID0gcC5fZ2V0QmV0YSgpO1xuXG4gICAgaWYgKHNwbGl0LmsxLm5lZ2F0aXZlKSB7XG4gICAgICBzcGxpdC5rMS5pbmVnKCk7XG4gICAgICBwID0gcC5uZWcodHJ1ZSk7XG4gICAgfVxuICAgIGlmIChzcGxpdC5rMi5uZWdhdGl2ZSkge1xuICAgICAgc3BsaXQuazIuaW5lZygpO1xuICAgICAgYmV0YSA9IGJldGEubmVnKHRydWUpO1xuICAgIH1cblxuICAgIG5wb2ludHNbaSAqIDJdID0gcDtcbiAgICBucG9pbnRzW2kgKiAyICsgMV0gPSBiZXRhO1xuICAgIG5jb2VmZnNbaSAqIDJdID0gc3BsaXQuazE7XG4gICAgbmNvZWZmc1tpICogMiArIDFdID0gc3BsaXQuazI7XG4gIH1cbiAgdmFyIHJlcyA9IHRoaXMuX3duYWZNdWxBZGQoMSwgbnBvaW50cywgbmNvZWZmcywgaSAqIDIpO1xuXG4gIC8vIENsZWFuLXVwIHJlZmVyZW5jZXMgdG8gcG9pbnRzIGFuZCBjb2VmZmljaWVudHNcbiAgZm9yICh2YXIgaiA9IDA7IGogPCBpICogMjsgaisrKSB7XG4gICAgbnBvaW50c1tqXSA9IG51bGw7XG4gICAgbmNvZWZmc1tqXSA9IG51bGw7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn07XG5cbmZ1bmN0aW9uIFBvaW50KGN1cnZlLCB4LCB5LCBpc1JlZCkge1xuICBCYXNlLkJhc2VQb2ludC5jYWxsKHRoaXMsIGN1cnZlLCAnYWZmaW5lJyk7XG4gIGlmICh4ID09PSBudWxsICYmIHkgPT09IG51bGwpIHtcbiAgICB0aGlzLnggPSBudWxsO1xuICAgIHRoaXMueSA9IG51bGw7XG4gICAgdGhpcy5pbmYgPSB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHRoaXMueCA9IG5ldyBCTih4LCAxNik7XG4gICAgdGhpcy55ID0gbmV3IEJOKHksIDE2KTtcbiAgICAvLyBGb3JjZSByZWRnb21lcnkgcmVwcmVzZW50YXRpb24gd2hlbiBsb2FkaW5nIGZyb20gSlNPTlxuICAgIGlmIChpc1JlZCkge1xuICAgICAgdGhpcy54LmZvcmNlUmVkKHRoaXMuY3VydmUucmVkKTtcbiAgICAgIHRoaXMueS5mb3JjZVJlZCh0aGlzLmN1cnZlLnJlZCk7XG4gICAgfVxuICAgIGlmICghdGhpcy54LnJlZClcbiAgICAgIHRoaXMueCA9IHRoaXMueC50b1JlZCh0aGlzLmN1cnZlLnJlZCk7XG4gICAgaWYgKCF0aGlzLnkucmVkKVxuICAgICAgdGhpcy55ID0gdGhpcy55LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcbiAgICB0aGlzLmluZiA9IGZhbHNlO1xuICB9XG59XG5pbmhlcml0cyhQb2ludCwgQmFzZS5CYXNlUG9pbnQpO1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS5wb2ludCA9IGZ1bmN0aW9uIHBvaW50KHgsIHksIGlzUmVkKSB7XG4gIHJldHVybiBuZXcgUG9pbnQodGhpcywgeCwgeSwgaXNSZWQpO1xufTtcblxuU2hvcnRDdXJ2ZS5wcm90b3R5cGUucG9pbnRGcm9tSlNPTiA9IGZ1bmN0aW9uIHBvaW50RnJvbUpTT04ob2JqLCByZWQpIHtcbiAgcmV0dXJuIFBvaW50LmZyb21KU09OKHRoaXMsIG9iaiwgcmVkKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5fZ2V0QmV0YSA9IGZ1bmN0aW9uIF9nZXRCZXRhKCkge1xuICBpZiAoIXRoaXMuY3VydmUuZW5kbylcbiAgICByZXR1cm47XG5cbiAgdmFyIHByZSA9IHRoaXMucHJlY29tcHV0ZWQ7XG4gIGlmIChwcmUgJiYgcHJlLmJldGEpXG4gICAgcmV0dXJuIHByZS5iZXRhO1xuXG4gIHZhciBiZXRhID0gdGhpcy5jdXJ2ZS5wb2ludCh0aGlzLngucmVkTXVsKHRoaXMuY3VydmUuZW5kby5iZXRhKSwgdGhpcy55KTtcbiAgaWYgKHByZSkge1xuICAgIHZhciBjdXJ2ZSA9IHRoaXMuY3VydmU7XG4gICAgdmFyIGVuZG9NdWwgPSBmdW5jdGlvbihwKSB7XG4gICAgICByZXR1cm4gY3VydmUucG9pbnQocC54LnJlZE11bChjdXJ2ZS5lbmRvLmJldGEpLCBwLnkpO1xuICAgIH07XG4gICAgcHJlLmJldGEgPSBiZXRhO1xuICAgIGJldGEucHJlY29tcHV0ZWQgPSB7XG4gICAgICBiZXRhOiBudWxsLFxuICAgICAgbmFmOiBwcmUubmFmICYmIHtcbiAgICAgICAgd25kOiBwcmUubmFmLnduZCxcbiAgICAgICAgcG9pbnRzOiBwcmUubmFmLnBvaW50cy5tYXAoZW5kb011bClcbiAgICAgIH0sXG4gICAgICBkb3VibGVzOiBwcmUuZG91YmxlcyAmJiB7XG4gICAgICAgIHN0ZXA6IHByZS5kb3VibGVzLnN0ZXAsXG4gICAgICAgIHBvaW50czogcHJlLmRvdWJsZXMucG9pbnRzLm1hcChlbmRvTXVsKVxuICAgICAgfVxuICAgIH07XG4gIH1cbiAgcmV0dXJuIGJldGE7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICBpZiAoIXRoaXMucHJlY29tcHV0ZWQpXG4gICAgcmV0dXJuIFsgdGhpcy54LCB0aGlzLnkgXTtcblxuICByZXR1cm4gWyB0aGlzLngsIHRoaXMueSwgdGhpcy5wcmVjb21wdXRlZCAmJiB7XG4gICAgZG91YmxlczogdGhpcy5wcmVjb21wdXRlZC5kb3VibGVzICYmIHtcbiAgICAgIHN0ZXA6IHRoaXMucHJlY29tcHV0ZWQuZG91Ymxlcy5zdGVwLFxuICAgICAgcG9pbnRzOiB0aGlzLnByZWNvbXB1dGVkLmRvdWJsZXMucG9pbnRzLnNsaWNlKDEpXG4gICAgfSxcbiAgICBuYWY6IHRoaXMucHJlY29tcHV0ZWQubmFmICYmIHtcbiAgICAgIHduZDogdGhpcy5wcmVjb21wdXRlZC5uYWYud25kLFxuICAgICAgcG9pbnRzOiB0aGlzLnByZWNvbXB1dGVkLm5hZi5wb2ludHMuc2xpY2UoMSlcbiAgICB9XG4gIH0gXTtcbn07XG5cblBvaW50LmZyb21KU09OID0gZnVuY3Rpb24gZnJvbUpTT04oY3VydmUsIG9iaiwgcmVkKSB7XG4gIGlmICh0eXBlb2Ygb2JqID09PSAnc3RyaW5nJylcbiAgICBvYmogPSBKU09OLnBhcnNlKG9iaik7XG4gIHZhciByZXMgPSBjdXJ2ZS5wb2ludChvYmpbMF0sIG9ialsxXSwgcmVkKTtcbiAgaWYgKCFvYmpbMl0pXG4gICAgcmV0dXJuIHJlcztcblxuICBmdW5jdGlvbiBvYmoycG9pbnQob2JqKSB7XG4gICAgcmV0dXJuIGN1cnZlLnBvaW50KG9ialswXSwgb2JqWzFdLCByZWQpO1xuICB9XG5cbiAgdmFyIHByZSA9IG9ialsyXTtcbiAgcmVzLnByZWNvbXB1dGVkID0ge1xuICAgIGJldGE6IG51bGwsXG4gICAgZG91YmxlczogcHJlLmRvdWJsZXMgJiYge1xuICAgICAgc3RlcDogcHJlLmRvdWJsZXMuc3RlcCxcbiAgICAgIHBvaW50czogWyByZXMgXS5jb25jYXQocHJlLmRvdWJsZXMucG9pbnRzLm1hcChvYmoycG9pbnQpKVxuICAgIH0sXG4gICAgbmFmOiBwcmUubmFmICYmIHtcbiAgICAgIHduZDogcHJlLm5hZi53bmQsXG4gICAgICBwb2ludHM6IFsgcmVzIF0uY29uY2F0KHByZS5uYWYucG9pbnRzLm1hcChvYmoycG9pbnQpKVxuICAgIH1cbiAgfTtcbiAgcmV0dXJuIHJlcztcbn07XG5cblBvaW50LnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiAnPEVDIFBvaW50IEluZmluaXR5Pic7XG4gIHJldHVybiAnPEVDIFBvaW50IHg6ICcgKyB0aGlzLnguZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArXG4gICAgICAnIHk6ICcgKyB0aGlzLnkuZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArICc+Jztcbn07XG5cblBvaW50LnByb3RvdHlwZS5pc0luZmluaXR5ID0gZnVuY3Rpb24gaXNJbmZpbml0eSgpIHtcbiAgcmV0dXJuIHRoaXMuaW5mO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZChwKSB7XG4gIC8vIE8gKyBQID0gUFxuICBpZiAodGhpcy5pbmYpXG4gICAgcmV0dXJuIHA7XG5cbiAgLy8gUCArIE8gPSBQXG4gIGlmIChwLmluZilcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBQICsgUCA9IDJQXG4gIGlmICh0aGlzLmVxKHApKVxuICAgIHJldHVybiB0aGlzLmRibCgpO1xuXG4gIC8vIFAgKyAoLVApID0gT1xuICBpZiAodGhpcy5uZWcoKS5lcShwKSlcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChudWxsLCBudWxsKTtcblxuICAvLyBQICsgUSA9IE9cbiAgaWYgKHRoaXMueC5jbXAocC54KSA9PT0gMClcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChudWxsLCBudWxsKTtcblxuICB2YXIgYyA9IHRoaXMueS5yZWRTdWIocC55KTtcbiAgaWYgKGMuY21wbigwKSAhPT0gMClcbiAgICBjID0gYy5yZWRNdWwodGhpcy54LnJlZFN1YihwLngpLnJlZEludm0oKSk7XG4gIHZhciBueCA9IGMucmVkU3FyKCkucmVkSVN1Yih0aGlzLngpLnJlZElTdWIocC54KTtcbiAgdmFyIG55ID0gYy5yZWRNdWwodGhpcy54LnJlZFN1YihueCkpLnJlZElTdWIodGhpcy55KTtcbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobngsIG55KTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5kYmwgPSBmdW5jdGlvbiBkYmwoKSB7XG4gIGlmICh0aGlzLmluZilcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyAyUCA9IE9cbiAgdmFyIHlzMSA9IHRoaXMueS5yZWRBZGQodGhpcy55KTtcbiAgaWYgKHlzMS5jbXBuKDApID09PSAwKVxuICAgIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG51bGwsIG51bGwpO1xuXG4gIHZhciBhID0gdGhpcy5jdXJ2ZS5hO1xuXG4gIHZhciB4MiA9IHRoaXMueC5yZWRTcXIoKTtcbiAgdmFyIGR5aW52ID0geXMxLnJlZEludm0oKTtcbiAgdmFyIGMgPSB4Mi5yZWRBZGQoeDIpLnJlZElBZGQoeDIpLnJlZElBZGQoYSkucmVkTXVsKGR5aW52KTtcblxuICB2YXIgbnggPSBjLnJlZFNxcigpLnJlZElTdWIodGhpcy54LnJlZEFkZCh0aGlzLngpKTtcbiAgdmFyIG55ID0gYy5yZWRNdWwodGhpcy54LnJlZFN1YihueCkpLnJlZElTdWIodGhpcy55KTtcbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobngsIG55KTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5nZXRYID0gZnVuY3Rpb24gZ2V0WCgpIHtcbiAgcmV0dXJuIHRoaXMueC5mcm9tUmVkKCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZ2V0WSA9IGZ1bmN0aW9uIGdldFkoKSB7XG4gIHJldHVybiB0aGlzLnkuZnJvbVJlZCgpO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm11bCA9IGZ1bmN0aW9uIG11bChrKSB7XG4gIGsgPSBuZXcgQk4oaywgMTYpO1xuXG4gIGlmICh0aGlzLl9oYXNEb3VibGVzKGspKVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl9maXhlZE5hZk11bCh0aGlzLCBrKTtcbiAgZWxzZSBpZiAodGhpcy5jdXJ2ZS5lbmRvKVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl9lbmRvV25hZk11bEFkZChbIHRoaXMgXSwgWyBrIF0pO1xuICBlbHNlXG4gICAgcmV0dXJuIHRoaXMuY3VydmUuX3duYWZNdWwodGhpcywgayk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUubXVsQWRkID0gZnVuY3Rpb24gbXVsQWRkKGsxLCBwMiwgazIpIHtcbiAgdmFyIHBvaW50cyA9IFsgdGhpcywgcDIgXTtcbiAgdmFyIGNvZWZmcyA9IFsgazEsIGsyIF07XG4gIGlmICh0aGlzLmN1cnZlLmVuZG8pXG4gICAgcmV0dXJuIHRoaXMuY3VydmUuX2VuZG9XbmFmTXVsQWRkKHBvaW50cywgY29lZmZzKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl93bmFmTXVsQWRkKDEsIHBvaW50cywgY29lZmZzLCAyKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5lcSA9IGZ1bmN0aW9uIGVxKHApIHtcbiAgcmV0dXJuIHRoaXMgPT09IHAgfHxcbiAgICAgICAgIHRoaXMuaW5mID09PSBwLmluZiAmJlxuICAgICAgICAgICAgICh0aGlzLmluZiB8fCB0aGlzLnguY21wKHAueCkgPT09IDAgJiYgdGhpcy55LmNtcChwLnkpID09PSAwKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5uZWcgPSBmdW5jdGlvbiBuZWcoX3ByZWNvbXB1dGUpIHtcbiAgaWYgKHRoaXMuaW5mKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIHZhciByZXMgPSB0aGlzLmN1cnZlLnBvaW50KHRoaXMueCwgdGhpcy55LnJlZE5lZygpKTtcbiAgaWYgKF9wcmVjb21wdXRlICYmIHRoaXMucHJlY29tcHV0ZWQpIHtcbiAgICB2YXIgcHJlID0gdGhpcy5wcmVjb21wdXRlZDtcbiAgICB2YXIgbmVnYXRlID0gZnVuY3Rpb24ocCkge1xuICAgICAgcmV0dXJuIHAubmVnKCk7XG4gICAgfTtcbiAgICByZXMucHJlY29tcHV0ZWQgPSB7XG4gICAgICBuYWY6IHByZS5uYWYgJiYge1xuICAgICAgICB3bmQ6IHByZS5uYWYud25kLFxuICAgICAgICBwb2ludHM6IHByZS5uYWYucG9pbnRzLm1hcChuZWdhdGUpXG4gICAgICB9LFxuICAgICAgZG91YmxlczogcHJlLmRvdWJsZXMgJiYge1xuICAgICAgICBzdGVwOiBwcmUuZG91Ymxlcy5zdGVwLFxuICAgICAgICBwb2ludHM6IHByZS5kb3VibGVzLnBvaW50cy5tYXAobmVnYXRlKVxuICAgICAgfVxuICAgIH07XG4gIH1cbiAgcmV0dXJuIHJlcztcbn07XG5cblBvaW50LnByb3RvdHlwZS50b0ogPSBmdW5jdGlvbiB0b0ooKSB7XG4gIGlmICh0aGlzLmluZilcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobnVsbCwgbnVsbCwgbnVsbCk7XG5cbiAgdmFyIHJlcyA9IHRoaXMuY3VydmUuanBvaW50KHRoaXMueCwgdGhpcy55LCB0aGlzLmN1cnZlLm9uZSk7XG4gIHJldHVybiByZXM7XG59O1xuXG5mdW5jdGlvbiBKUG9pbnQoY3VydmUsIHgsIHksIHopIHtcbiAgQmFzZS5CYXNlUG9pbnQuY2FsbCh0aGlzLCBjdXJ2ZSwgJ2phY29iaWFuJyk7XG4gIGlmICh4ID09PSBudWxsICYmIHkgPT09IG51bGwgJiYgeiA9PT0gbnVsbCkge1xuICAgIHRoaXMueCA9IHRoaXMuY3VydmUub25lO1xuICAgIHRoaXMueSA9IHRoaXMuY3VydmUub25lO1xuICAgIHRoaXMueiA9IG5ldyBCTigwKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnggPSBuZXcgQk4oeCwgMTYpO1xuICAgIHRoaXMueSA9IG5ldyBCTih5LCAxNik7XG4gICAgdGhpcy56ID0gbmV3IEJOKHosIDE2KTtcbiAgfVxuICBpZiAoIXRoaXMueC5yZWQpXG4gICAgdGhpcy54ID0gdGhpcy54LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcbiAgaWYgKCF0aGlzLnkucmVkKVxuICAgIHRoaXMueSA9IHRoaXMueS50b1JlZCh0aGlzLmN1cnZlLnJlZCk7XG4gIGlmICghdGhpcy56LnJlZClcbiAgICB0aGlzLnogPSB0aGlzLnoudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuXG4gIHRoaXMuek9uZSA9IHRoaXMueiA9PT0gdGhpcy5jdXJ2ZS5vbmU7XG59XG5pbmhlcml0cyhKUG9pbnQsIEJhc2UuQmFzZVBvaW50KTtcblxuU2hvcnRDdXJ2ZS5wcm90b3R5cGUuanBvaW50ID0gZnVuY3Rpb24ganBvaW50KHgsIHksIHopIHtcbiAgcmV0dXJuIG5ldyBKUG9pbnQodGhpcywgeCwgeSwgeik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLnRvUCA9IGZ1bmN0aW9uIHRvUCgpIHtcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG51bGwsIG51bGwpO1xuXG4gIHZhciB6aW52ID0gdGhpcy56LnJlZEludm0oKTtcbiAgdmFyIHppbnYyID0gemludi5yZWRTcXIoKTtcbiAgdmFyIGF4ID0gdGhpcy54LnJlZE11bCh6aW52Mik7XG4gIHZhciBheSA9IHRoaXMueS5yZWRNdWwoemludjIpLnJlZE11bCh6aW52KTtcblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChheCwgYXkpO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS5uZWcgPSBmdW5jdGlvbiBuZWcoKSB7XG4gIHJldHVybiB0aGlzLmN1cnZlLmpwb2ludCh0aGlzLngsIHRoaXMueS5yZWROZWcoKSwgdGhpcy56KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gYWRkKHApIHtcbiAgLy8gTyArIFAgPSBQXG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gcDtcblxuICAvLyBQICsgTyA9IFBcbiAgaWYgKHAuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIC8vIDEyTSArIDRTICsgN0FcbiAgdmFyIHB6MiA9IHAuei5yZWRTcXIoKTtcbiAgdmFyIHoyID0gdGhpcy56LnJlZFNxcigpO1xuICB2YXIgdTEgPSB0aGlzLngucmVkTXVsKHB6Mik7XG4gIHZhciB1MiA9IHAueC5yZWRNdWwoejIpO1xuICB2YXIgczEgPSB0aGlzLnkucmVkTXVsKHB6Mi5yZWRNdWwocC56KSk7XG4gIHZhciBzMiA9IHAueS5yZWRNdWwoejIucmVkTXVsKHRoaXMueikpO1xuXG4gIHZhciBoID0gdTEucmVkU3ViKHUyKTtcbiAgdmFyIHIgPSBzMS5yZWRTdWIoczIpO1xuICBpZiAoaC5jbXBuKDApID09PSAwKSB7XG4gICAgaWYgKHIuY21wbigwKSAhPT0gMClcbiAgICAgIHJldHVybiB0aGlzLmN1cnZlLmpwb2ludChudWxsLCBudWxsLCBudWxsKTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gdGhpcy5kYmwoKTtcbiAgfVxuXG4gIHZhciBoMiA9IGgucmVkU3FyKCk7XG4gIHZhciBoMyA9IGgyLnJlZE11bChoKTtcbiAgdmFyIHYgPSB1MS5yZWRNdWwoaDIpO1xuXG4gIHZhciBueCA9IHIucmVkU3FyKCkucmVkSUFkZChoMykucmVkSVN1Yih2KS5yZWRJU3ViKHYpO1xuICB2YXIgbnkgPSByLnJlZE11bCh2LnJlZElTdWIobngpKS5yZWRJU3ViKHMxLnJlZE11bChoMykpO1xuICB2YXIgbnogPSB0aGlzLnoucmVkTXVsKHAueikucmVkTXVsKGgpO1xuXG4gIHJldHVybiB0aGlzLmN1cnZlLmpwb2ludChueCwgbnksIG56KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUubWl4ZWRBZGQgPSBmdW5jdGlvbiBtaXhlZEFkZChwKSB7XG4gIC8vIE8gKyBQID0gUFxuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHAudG9KKCk7XG5cbiAgLy8gUCArIE8gPSBQXG4gIGlmIChwLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyA4TSArIDNTICsgN0FcbiAgdmFyIHoyID0gdGhpcy56LnJlZFNxcigpO1xuICB2YXIgdTEgPSB0aGlzLng7XG4gIHZhciB1MiA9IHAueC5yZWRNdWwoejIpO1xuICB2YXIgczEgPSB0aGlzLnk7XG4gIHZhciBzMiA9IHAueS5yZWRNdWwoejIpLnJlZE11bCh0aGlzLnopO1xuXG4gIHZhciBoID0gdTEucmVkU3ViKHUyKTtcbiAgdmFyIHIgPSBzMS5yZWRTdWIoczIpO1xuICBpZiAoaC5jbXBuKDApID09PSAwKSB7XG4gICAgaWYgKHIuY21wbigwKSAhPT0gMClcbiAgICAgIHJldHVybiB0aGlzLmN1cnZlLmpwb2ludChudWxsLCBudWxsLCBudWxsKTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gdGhpcy5kYmwoKTtcbiAgfVxuXG4gIHZhciBoMiA9IGgucmVkU3FyKCk7XG4gIHZhciBoMyA9IGgyLnJlZE11bChoKTtcbiAgdmFyIHYgPSB1MS5yZWRNdWwoaDIpO1xuXG4gIHZhciBueCA9IHIucmVkU3FyKCkucmVkSUFkZChoMykucmVkSVN1Yih2KS5yZWRJU3ViKHYpO1xuICB2YXIgbnkgPSByLnJlZE11bCh2LnJlZElTdWIobngpKS5yZWRJU3ViKHMxLnJlZE11bChoMykpO1xuICB2YXIgbnogPSB0aGlzLnoucmVkTXVsKGgpO1xuXG4gIHJldHVybiB0aGlzLmN1cnZlLmpwb2ludChueCwgbnksIG56KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUuZGJscCA9IGZ1bmN0aW9uIGRibHAocG93KSB7XG4gIGlmIChwb3cgPT09IDApXG4gICAgcmV0dXJuIHRoaXM7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gdGhpcztcbiAgaWYgKCFwb3cpXG4gICAgcmV0dXJuIHRoaXMuZGJsKCk7XG5cbiAgaWYgKHRoaXMuY3VydmUuemVyb0EgfHwgdGhpcy5jdXJ2ZS50aHJlZUEpIHtcbiAgICB2YXIgciA9IHRoaXM7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwb3c7IGkrKylcbiAgICAgIHIgPSByLmRibCgpO1xuICAgIHJldHVybiByO1xuICB9XG5cbiAgLy8gMU0gKyAyUyArIDFBICsgTiAqICg0UyArIDVNICsgOEEpXG4gIC8vIE4gPSAxID0+IDZNICsgNlMgKyA5QVxuICB2YXIgYSA9IHRoaXMuY3VydmUuYTtcbiAgdmFyIHRpbnYgPSB0aGlzLmN1cnZlLnRpbnY7XG5cbiAgdmFyIGp4ID0gdGhpcy54O1xuICB2YXIgankgPSB0aGlzLnk7XG4gIHZhciBqeiA9IHRoaXMuejtcbiAgdmFyIGp6NCA9IGp6LnJlZFNxcigpLnJlZFNxcigpO1xuXG4gIC8vIFJldXNlIHJlc3VsdHNcbiAgdmFyIGp5ZCA9IGp5LnJlZEFkZChqeSk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcG93OyBpKyspIHtcbiAgICB2YXIgangyID0gangucmVkU3FyKCk7XG4gICAgdmFyIGp5ZDIgPSBqeWQucmVkU3FyKCk7XG4gICAgdmFyIGp5ZDQgPSBqeWQyLnJlZFNxcigpO1xuICAgIHZhciBjID0gangyLnJlZEFkZChqeDIpLnJlZElBZGQoangyKS5yZWRJQWRkKGEucmVkTXVsKGp6NCkpO1xuXG4gICAgdmFyIHQxID0gangucmVkTXVsKGp5ZDIpO1xuICAgIHZhciBueCA9IGMucmVkU3FyKCkucmVkSVN1Yih0MS5yZWRBZGQodDEpKTtcbiAgICB2YXIgdDIgPSB0MS5yZWRJU3ViKG54KTtcbiAgICB2YXIgZG55ID0gYy5yZWRNdWwodDIpO1xuICAgIGRueSA9IGRueS5yZWRJQWRkKGRueSkucmVkSVN1YihqeWQ0KTtcbiAgICB2YXIgbnogPSBqeWQucmVkTXVsKGp6KTtcbiAgICBpZiAoaSArIDEgPCBwb3cpXG4gICAgICBqejQgPSBqejQucmVkTXVsKGp5ZDQpO1xuXG4gICAganggPSBueDtcbiAgICBqeiA9IG56O1xuICAgIGp5ZCA9IGRueTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmN1cnZlLmpwb2ludChqeCwganlkLnJlZE11bCh0aW52KSwganopO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS5kYmwgPSBmdW5jdGlvbiBkYmwoKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gdGhpcztcblxuICBpZiAodGhpcy5jdXJ2ZS56ZXJvQSlcbiAgICByZXR1cm4gdGhpcy5femVyb0RibCgpO1xuICBlbHNlIGlmICh0aGlzLmN1cnZlLnRocmVlQSlcbiAgICByZXR1cm4gdGhpcy5fdGhyZWVEYmwoKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLl9kYmwoKTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUuX3plcm9EYmwgPSBmdW5jdGlvbiBfemVyb0RibCgpIHtcbiAgdmFyIG54O1xuICB2YXIgbnk7XG4gIHZhciBuejtcbiAgLy8gWiA9IDFcbiAgaWYgKHRoaXMuek9uZSkge1xuICAgIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by1zaG9ydHctamFjb2JpYW4tMC5odG1sXG4gICAgLy8gICAgICNkb3VibGluZy1tZGJsLTIwMDctYmxcbiAgICAvLyAxTSArIDVTICsgMTRBXG5cbiAgICAvLyBYWCA9IFgxXjJcbiAgICB2YXIgeHggPSB0aGlzLngucmVkU3FyKCk7XG4gICAgLy8gWVkgPSBZMV4yXG4gICAgdmFyIHl5ID0gdGhpcy55LnJlZFNxcigpO1xuICAgIC8vIFlZWVkgPSBZWV4yXG4gICAgdmFyIHl5eXkgPSB5eS5yZWRTcXIoKTtcbiAgICAvLyBTID0gMiAqICgoWDEgKyBZWSleMiAtIFhYIC0gWVlZWSlcbiAgICB2YXIgcyA9IHRoaXMueC5yZWRBZGQoeXkpLnJlZFNxcigpLnJlZElTdWIoeHgpLnJlZElTdWIoeXl5eSk7XG4gICAgcyA9IHMucmVkSUFkZChzKTtcbiAgICAvLyBNID0gMyAqIFhYICsgYTsgYSA9IDBcbiAgICB2YXIgbSA9IHh4LnJlZEFkZCh4eCkucmVkSUFkZCh4eCk7XG4gICAgLy8gVCA9IE0gXiAyIC0gMipTXG4gICAgdmFyIHQgPSBtLnJlZFNxcigpLnJlZElTdWIocykucmVkSVN1YihzKTtcblxuICAgIC8vIDggKiBZWVlZXG4gICAgdmFyIHl5eXk4ID0geXl5eS5yZWRJQWRkKHl5eXkpO1xuICAgIHl5eXk4ID0geXl5eTgucmVkSUFkZCh5eXl5OCk7XG4gICAgeXl5eTggPSB5eXl5OC5yZWRJQWRkKHl5eXk4KTtcblxuICAgIC8vIFgzID0gVFxuICAgIG54ID0gdDtcbiAgICAvLyBZMyA9IE0gKiAoUyAtIFQpIC0gOCAqIFlZWVlcbiAgICBueSA9IG0ucmVkTXVsKHMucmVkSVN1Yih0KSkucmVkSVN1Yih5eXl5OCk7XG4gICAgLy8gWjMgPSAyKlkxXG4gICAgbnogPSB0aGlzLnkucmVkQWRkKHRoaXMueSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gaHlwZXJlbGxpcHRpYy5vcmcvRUZEL2cxcC9hdXRvLXNob3J0dy1qYWNvYmlhbi0wLmh0bWxcbiAgICAvLyAgICAgI2RvdWJsaW5nLWRibC0yMDA5LWxcbiAgICAvLyAyTSArIDVTICsgMTNBXG5cbiAgICAvLyBBID0gWDFeMlxuICAgIHZhciBhID0gdGhpcy54LnJlZFNxcigpO1xuICAgIC8vIEIgPSBZMV4yXG4gICAgdmFyIGIgPSB0aGlzLnkucmVkU3FyKCk7XG4gICAgLy8gQyA9IEJeMlxuICAgIHZhciBjID0gYi5yZWRTcXIoKTtcbiAgICAvLyBEID0gMiAqICgoWDEgKyBCKV4yIC0gQSAtIEMpXG4gICAgdmFyIGQgPSB0aGlzLngucmVkQWRkKGIpLnJlZFNxcigpLnJlZElTdWIoYSkucmVkSVN1YihjKTtcbiAgICBkID0gZC5yZWRJQWRkKGQpO1xuICAgIC8vIEUgPSAzICogQVxuICAgIHZhciBlID0gYS5yZWRBZGQoYSkucmVkSUFkZChhKTtcbiAgICAvLyBGID0gRV4yXG4gICAgdmFyIGYgPSBlLnJlZFNxcigpO1xuXG4gICAgLy8gOCAqIENcbiAgICB2YXIgYzggPSBjLnJlZElBZGQoYyk7XG4gICAgYzggPSBjOC5yZWRJQWRkKGM4KTtcbiAgICBjOCA9IGM4LnJlZElBZGQoYzgpO1xuXG4gICAgLy8gWDMgPSBGIC0gMiAqIERcbiAgICBueCA9IGYucmVkSVN1YihkKS5yZWRJU3ViKGQpO1xuICAgIC8vIFkzID0gRSAqIChEIC0gWDMpIC0gOCAqIENcbiAgICBueSA9IGUucmVkTXVsKGQucmVkSVN1YihueCkpLnJlZElTdWIoYzgpO1xuICAgIC8vIFozID0gMiAqIFkxICogWjFcbiAgICBueiA9IHRoaXMueS5yZWRNdWwodGhpcy56KTtcbiAgICBueiA9IG56LnJlZElBZGQobnopO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuY3VydmUuanBvaW50KG54LCBueSwgbnopO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS5fdGhyZWVEYmwgPSBmdW5jdGlvbiBfdGhyZWVEYmwoKSB7XG4gIHZhciBueDtcbiAgdmFyIG55O1xuICB2YXIgbno7XG4gIC8vIFogPSAxXG4gIGlmICh0aGlzLnpPbmUpIHtcbiAgICAvLyBoeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tc2hvcnR3LWphY29iaWFuLTMuaHRtbFxuICAgIC8vICAgICAjZG91YmxpbmctbWRibC0yMDA3LWJsXG4gICAgLy8gMU0gKyA1UyArIDE1QVxuXG4gICAgLy8gWFggPSBYMV4yXG4gICAgdmFyIHh4ID0gdGhpcy54LnJlZFNxcigpO1xuICAgIC8vIFlZID0gWTFeMlxuICAgIHZhciB5eSA9IHRoaXMueS5yZWRTcXIoKTtcbiAgICAvLyBZWVlZID0gWVleMlxuICAgIHZhciB5eXl5ID0geXkucmVkU3FyKCk7XG4gICAgLy8gUyA9IDIgKiAoKFgxICsgWVkpXjIgLSBYWCAtIFlZWVkpXG4gICAgdmFyIHMgPSB0aGlzLngucmVkQWRkKHl5KS5yZWRTcXIoKS5yZWRJU3ViKHh4KS5yZWRJU3ViKHl5eXkpO1xuICAgIHMgPSBzLnJlZElBZGQocyk7XG4gICAgLy8gTSA9IDMgKiBYWCArIGFcbiAgICB2YXIgbSA9IHh4LnJlZEFkZCh4eCkucmVkSUFkZCh4eCkucmVkSUFkZCh0aGlzLmN1cnZlLmEpO1xuICAgIC8vIFQgPSBNXjIgLSAyICogU1xuICAgIHZhciB0ID0gbS5yZWRTcXIoKS5yZWRJU3ViKHMpLnJlZElTdWIocyk7XG4gICAgLy8gWDMgPSBUXG4gICAgbnggPSB0O1xuICAgIC8vIFkzID0gTSAqIChTIC0gVCkgLSA4ICogWVlZWVxuICAgIHZhciB5eXl5OCA9IHl5eXkucmVkSUFkZCh5eXl5KTtcbiAgICB5eXl5OCA9IHl5eXk4LnJlZElBZGQoeXl5eTgpO1xuICAgIHl5eXk4ID0geXl5eTgucmVkSUFkZCh5eXl5OCk7XG4gICAgbnkgPSBtLnJlZE11bChzLnJlZElTdWIodCkpLnJlZElTdWIoeXl5eTgpO1xuICAgIC8vIFozID0gMiAqIFkxXG4gICAgbnogPSB0aGlzLnkucmVkQWRkKHRoaXMueSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gaHlwZXJlbGxpcHRpYy5vcmcvRUZEL2cxcC9hdXRvLXNob3J0dy1qYWNvYmlhbi0zLmh0bWwjZG91YmxpbmctZGJsLTIwMDEtYlxuICAgIC8vIDNNICsgNVNcblxuICAgIC8vIGRlbHRhID0gWjFeMlxuICAgIHZhciBkZWx0YSA9IHRoaXMuei5yZWRTcXIoKTtcbiAgICAvLyBnYW1tYSA9IFkxXjJcbiAgICB2YXIgZ2FtbWEgPSB0aGlzLnkucmVkU3FyKCk7XG4gICAgLy8gYmV0YSA9IFgxICogZ2FtbWFcbiAgICB2YXIgYmV0YSA9IHRoaXMueC5yZWRNdWwoZ2FtbWEpO1xuICAgIC8vIGFscGhhID0gMyAqIChYMSAtIGRlbHRhKSAqIChYMSArIGRlbHRhKVxuICAgIHZhciBhbHBoYSA9IHRoaXMueC5yZWRTdWIoZGVsdGEpLnJlZE11bCh0aGlzLngucmVkQWRkKGRlbHRhKSk7XG4gICAgYWxwaGEgPSBhbHBoYS5yZWRBZGQoYWxwaGEpLnJlZElBZGQoYWxwaGEpO1xuICAgIC8vIFgzID0gYWxwaGFeMiAtIDggKiBiZXRhXG4gICAgdmFyIGJldGE0ID0gYmV0YS5yZWRJQWRkKGJldGEpO1xuICAgIGJldGE0ID0gYmV0YTQucmVkSUFkZChiZXRhNCk7XG4gICAgdmFyIGJldGE4ID0gYmV0YTQucmVkQWRkKGJldGE0KTtcbiAgICBueCA9IGFscGhhLnJlZFNxcigpLnJlZElTdWIoYmV0YTgpO1xuICAgIC8vIFozID0gKFkxICsgWjEpXjIgLSBnYW1tYSAtIGRlbHRhXG4gICAgbnogPSB0aGlzLnkucmVkQWRkKHRoaXMueikucmVkU3FyKCkucmVkSVN1YihnYW1tYSkucmVkSVN1YihkZWx0YSk7XG4gICAgLy8gWTMgPSBhbHBoYSAqICg0ICogYmV0YSAtIFgzKSAtIDggKiBnYW1tYV4yXG4gICAgdmFyIGdnYW1tYTggPSBnYW1tYS5yZWRTcXIoKTtcbiAgICBnZ2FtbWE4ID0gZ2dhbW1hOC5yZWRJQWRkKGdnYW1tYTgpO1xuICAgIGdnYW1tYTggPSBnZ2FtbWE4LnJlZElBZGQoZ2dhbW1hOCk7XG4gICAgZ2dhbW1hOCA9IGdnYW1tYTgucmVkSUFkZChnZ2FtbWE4KTtcbiAgICBueSA9IGFscGhhLnJlZE11bChiZXRhNC5yZWRJU3ViKG54KSkucmVkSVN1YihnZ2FtbWE4KTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmN1cnZlLmpwb2ludChueCwgbnksIG56KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUuX2RibCA9IGZ1bmN0aW9uIF9kYmwoKSB7XG4gIHZhciBhID0gdGhpcy5jdXJ2ZS5hO1xuXG4gIC8vIDRNICsgNlMgKyAxMEFcbiAgdmFyIGp4ID0gdGhpcy54O1xuICB2YXIgankgPSB0aGlzLnk7XG4gIHZhciBqeiA9IHRoaXMuejtcbiAgdmFyIGp6NCA9IGp6LnJlZFNxcigpLnJlZFNxcigpO1xuXG4gIHZhciBqeDIgPSBqeC5yZWRTcXIoKTtcbiAgdmFyIGp5MiA9IGp5LnJlZFNxcigpO1xuXG4gIHZhciBjID0gangyLnJlZEFkZChqeDIpLnJlZElBZGQoangyKS5yZWRJQWRkKGEucmVkTXVsKGp6NCkpO1xuXG4gIHZhciBqeGQ0ID0gangucmVkQWRkKGp4KTtcbiAganhkNCA9IGp4ZDQucmVkSUFkZChqeGQ0KTtcbiAgdmFyIHQxID0ganhkNC5yZWRNdWwoankyKTtcbiAgdmFyIG54ID0gYy5yZWRTcXIoKS5yZWRJU3ViKHQxLnJlZEFkZCh0MSkpO1xuICB2YXIgdDIgPSB0MS5yZWRJU3ViKG54KTtcblxuICB2YXIganlkOCA9IGp5Mi5yZWRTcXIoKTtcbiAganlkOCA9IGp5ZDgucmVkSUFkZChqeWQ4KTtcbiAganlkOCA9IGp5ZDgucmVkSUFkZChqeWQ4KTtcbiAganlkOCA9IGp5ZDgucmVkSUFkZChqeWQ4KTtcbiAgdmFyIG55ID0gYy5yZWRNdWwodDIpLnJlZElTdWIoanlkOCk7XG4gIHZhciBueiA9IGp5LnJlZEFkZChqeSkucmVkTXVsKGp6KTtcblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobngsIG55LCBueik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLnRycGwgPSBmdW5jdGlvbiB0cnBsKCkge1xuICBpZiAoIXRoaXMuY3VydmUuemVyb0EpXG4gICAgcmV0dXJuIHRoaXMuZGJsKCkuYWRkKHRoaXMpO1xuXG4gIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by1zaG9ydHctamFjb2JpYW4tMC5odG1sI3RyaXBsaW5nLXRwbC0yMDA3LWJsXG4gIC8vIDVNICsgMTBTICsgLi4uXG5cbiAgLy8gWFggPSBYMV4yXG4gIHZhciB4eCA9IHRoaXMueC5yZWRTcXIoKTtcbiAgLy8gWVkgPSBZMV4yXG4gIHZhciB5eSA9IHRoaXMueS5yZWRTcXIoKTtcbiAgLy8gWlogPSBaMV4yXG4gIHZhciB6eiA9IHRoaXMuei5yZWRTcXIoKTtcbiAgLy8gWVlZWSA9IFlZXjJcbiAgdmFyIHl5eXkgPSB5eS5yZWRTcXIoKTtcbiAgLy8gTSA9IDMgKiBYWCArIGEgKiBaWjI7IGEgPSAwXG4gIHZhciBtID0geHgucmVkQWRkKHh4KS5yZWRJQWRkKHh4KTtcbiAgLy8gTU0gPSBNXjJcbiAgdmFyIG1tID0gbS5yZWRTcXIoKTtcbiAgLy8gRSA9IDYgKiAoKFgxICsgWVkpXjIgLSBYWCAtIFlZWVkpIC0gTU1cbiAgdmFyIGUgPSB0aGlzLngucmVkQWRkKHl5KS5yZWRTcXIoKS5yZWRJU3ViKHh4KS5yZWRJU3ViKHl5eXkpO1xuICBlID0gZS5yZWRJQWRkKGUpO1xuICBlID0gZS5yZWRBZGQoZSkucmVkSUFkZChlKTtcbiAgZSA9IGUucmVkSVN1YihtbSk7XG4gIC8vIEVFID0gRV4yXG4gIHZhciBlZSA9IGUucmVkU3FyKCk7XG4gIC8vIFQgPSAxNipZWVlZXG4gIHZhciB0ID0geXl5eS5yZWRJQWRkKHl5eXkpO1xuICB0ID0gdC5yZWRJQWRkKHQpO1xuICB0ID0gdC5yZWRJQWRkKHQpO1xuICB0ID0gdC5yZWRJQWRkKHQpO1xuICAvLyBVID0gKE0gKyBFKV4yIC0gTU0gLSBFRSAtIFRcbiAgdmFyIHUgPSBtLnJlZElBZGQoZSkucmVkU3FyKCkucmVkSVN1YihtbSkucmVkSVN1YihlZSkucmVkSVN1Yih0KTtcbiAgLy8gWDMgPSA0ICogKFgxICogRUUgLSA0ICogWVkgKiBVKVxuICB2YXIgeXl1NCA9IHl5LnJlZE11bCh1KTtcbiAgeXl1NCA9IHl5dTQucmVkSUFkZCh5eXU0KTtcbiAgeXl1NCA9IHl5dTQucmVkSUFkZCh5eXU0KTtcbiAgdmFyIG54ID0gdGhpcy54LnJlZE11bChlZSkucmVkSVN1Yih5eXU0KTtcbiAgbnggPSBueC5yZWRJQWRkKG54KTtcbiAgbnggPSBueC5yZWRJQWRkKG54KTtcbiAgLy8gWTMgPSA4ICogWTEgKiAoVSAqIChUIC0gVSkgLSBFICogRUUpXG4gIHZhciBueSA9IHRoaXMueS5yZWRNdWwodS5yZWRNdWwodC5yZWRJU3ViKHUpKS5yZWRJU3ViKGUucmVkTXVsKGVlKSkpO1xuICBueSA9IG55LnJlZElBZGQobnkpO1xuICBueSA9IG55LnJlZElBZGQobnkpO1xuICBueSA9IG55LnJlZElBZGQobnkpO1xuICAvLyBaMyA9IChaMSArIEUpXjIgLSBaWiAtIEVFXG4gIHZhciBueiA9IHRoaXMuei5yZWRBZGQoZSkucmVkU3FyKCkucmVkSVN1Yih6eikucmVkSVN1YihlZSk7XG5cbiAgcmV0dXJuIHRoaXMuY3VydmUuanBvaW50KG54LCBueSwgbnopO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS5tdWwgPSBmdW5jdGlvbiBtdWwoaywga2Jhc2UpIHtcbiAgayA9IG5ldyBCTihrLCBrYmFzZSk7XG5cbiAgcmV0dXJuIHRoaXMuY3VydmUuX3duYWZNdWwodGhpcywgayk7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLmVxID0gZnVuY3Rpb24gZXEocCkge1xuICBpZiAocC50eXBlID09PSAnYWZmaW5lJylcbiAgICByZXR1cm4gdGhpcy5lcShwLnRvSigpKTtcblxuICBpZiAodGhpcyA9PT0gcClcbiAgICByZXR1cm4gdHJ1ZTtcblxuICAvLyB4MSAqIHoyXjIgPT0geDIgKiB6MV4yXG4gIHZhciB6MiA9IHRoaXMuei5yZWRTcXIoKTtcbiAgdmFyIHB6MiA9IHAuei5yZWRTcXIoKTtcbiAgaWYgKHRoaXMueC5yZWRNdWwocHoyKS5yZWRJU3ViKHAueC5yZWRNdWwoejIpKS5jbXBuKDApICE9PSAwKVxuICAgIHJldHVybiBmYWxzZTtcblxuICAvLyB5MSAqIHoyXjMgPT0geTIgKiB6MV4zXG4gIHZhciB6MyA9IHoyLnJlZE11bCh0aGlzLnopO1xuICB2YXIgcHozID0gcHoyLnJlZE11bChwLnopO1xuICByZXR1cm4gdGhpcy55LnJlZE11bChwejMpLnJlZElTdWIocC55LnJlZE11bCh6MykpLmNtcG4oMCkgPT09IDA7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0KCkge1xuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuICc8RUMgSlBvaW50IEluZmluaXR5Pic7XG4gIHJldHVybiAnPEVDIEpQb2ludCB4OiAnICsgdGhpcy54LnRvU3RyaW5nKDE2LCAyKSArXG4gICAgICAnIHk6ICcgKyB0aGlzLnkudG9TdHJpbmcoMTYsIDIpICtcbiAgICAgICcgejogJyArIHRoaXMuei50b1N0cmluZygxNiwgMikgKyAnPic7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLmlzSW5maW5pdHkgPSBmdW5jdGlvbiBpc0luZmluaXR5KCkge1xuICAvLyBYWFggVGhpcyBjb2RlIGFzc3VtZXMgdGhhdCB6ZXJvIGlzIGFsd2F5cyB6ZXJvIGluIHJlZFxuICByZXR1cm4gdGhpcy56LmNtcG4oMCkgPT09IDA7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3VydmVzID0gZXhwb3J0cztcblxudmFyIGhhc2ggPSByZXF1aXJlKCdoYXNoLmpzJyk7XG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi9lbGxpcHRpYycpO1xuXG52YXIgYXNzZXJ0ID0gZWxsaXB0aWMudXRpbHMuYXNzZXJ0O1xuXG5mdW5jdGlvbiBQcmVzZXRDdXJ2ZShvcHRpb25zKSB7XG4gIGlmIChvcHRpb25zLnR5cGUgPT09ICdzaG9ydCcpXG4gICAgdGhpcy5jdXJ2ZSA9IG5ldyBlbGxpcHRpYy5jdXJ2ZS5zaG9ydChvcHRpb25zKTtcbiAgZWxzZSBpZiAob3B0aW9ucy50eXBlID09PSAnZWR3YXJkcycpXG4gICAgdGhpcy5jdXJ2ZSA9IG5ldyBlbGxpcHRpYy5jdXJ2ZS5lZHdhcmRzKG9wdGlvbnMpO1xuICBlbHNlXG4gICAgdGhpcy5jdXJ2ZSA9IG5ldyBlbGxpcHRpYy5jdXJ2ZS5tb250KG9wdGlvbnMpO1xuICB0aGlzLmcgPSB0aGlzLmN1cnZlLmc7XG4gIHRoaXMubiA9IHRoaXMuY3VydmUubjtcbiAgdGhpcy5oYXNoID0gb3B0aW9ucy5oYXNoO1xuXG4gIGFzc2VydCh0aGlzLmcudmFsaWRhdGUoKSwgJ0ludmFsaWQgY3VydmUnKTtcbiAgYXNzZXJ0KHRoaXMuZy5tdWwodGhpcy5uKS5pc0luZmluaXR5KCksICdJbnZhbGlkIGN1cnZlLCBHKk4gIT0gTycpO1xufVxuY3VydmVzLlByZXNldEN1cnZlID0gUHJlc2V0Q3VydmU7XG5cbmZ1bmN0aW9uIGRlZmluZUN1cnZlKG5hbWUsIG9wdGlvbnMpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN1cnZlcywgbmFtZSwge1xuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgY3VydmUgPSBuZXcgUHJlc2V0Q3VydmUob3B0aW9ucyk7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3VydmVzLCBuYW1lLCB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgdmFsdWU6IGN1cnZlXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBjdXJ2ZTtcbiAgICB9XG4gIH0pO1xufVxuXG5kZWZpbmVDdXJ2ZSgncDE5MicsIHtcbiAgdHlwZTogJ3Nob3J0JyxcbiAgcHJpbWU6ICdwMTkyJyxcbiAgcDogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZlIGZmZmZmZmZmIGZmZmZmZmZmJyxcbiAgYTogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZlIGZmZmZmZmZmIGZmZmZmZmZjJyxcbiAgYjogJzY0MjEwNTE5IGU1OWM4MGU3IDBmYTdlOWFiIDcyMjQzMDQ5IGZlYjhkZWVjIGMxNDZiOWIxJyxcbiAgbjogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIDk5ZGVmODM2IDE0NmJjOWIxIGI0ZDIyODMxJyxcbiAgaGFzaDogaGFzaC5zaGEyNTYsXG4gIGdSZWQ6IGZhbHNlLFxuICBnOiBbXG4gICAgJzE4OGRhODBlIGIwMzA5MGY2IDdjYmYyMGViIDQzYTE4ODAwIGY0ZmYwYWZkIDgyZmYxMDEyJyxcbiAgICAnMDcxOTJiOTUgZmZjOGRhNzggNjMxMDExZWQgNmIyNGNkZDUgNzNmOTc3YTEgMWU3OTQ4MTEnXG4gIF1cbn0pO1xuXG5kZWZpbmVDdXJ2ZSgncDIyNCcsIHtcbiAgdHlwZTogJ3Nob3J0JyxcbiAgcHJpbWU6ICdwMjI0JyxcbiAgcDogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIDAwMDAwMDAwIDAwMDAwMDAwIDAwMDAwMDAxJyxcbiAgYTogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZlIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZlJyxcbiAgYjogJ2I0MDUwYTg1IDBjMDRiM2FiIGY1NDEzMjU2IDUwNDRiMGI3IGQ3YmZkOGJhIDI3MGIzOTQzIDIzNTVmZmI0JyxcbiAgbjogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmYxNmEyIGUwYjhmMDNlIDEzZGQyOTQ1IDVjNWMyYTNkJyxcbiAgaGFzaDogaGFzaC5zaGEyNTYsXG4gIGdSZWQ6IGZhbHNlLFxuICBnOiBbXG4gICAgJ2I3MGUwY2JkIDZiYjRiZjdmIDMyMTM5MGI5IDRhMDNjMWQzIDU2YzIxMTIyIDM0MzI4MGQ2IDExNWMxZDIxJyxcbiAgICAnYmQzNzYzODggYjVmNzIzZmIgNGMyMmRmZTYgY2Q0Mzc1YTAgNWEwNzQ3NjQgNDRkNTgxOTkgODUwMDdlMzQnXG4gIF1cbn0pO1xuXG5kZWZpbmVDdXJ2ZSgncDI1NicsIHtcbiAgdHlwZTogJ3Nob3J0JyxcbiAgcHJpbWU6IG51bGwsXG4gIHA6ICdmZmZmZmZmZiAwMDAwMDAwMSAwMDAwMDAwMCAwMDAwMDAwMCAwMDAwMDAwMCBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZicsXG4gIGE6ICdmZmZmZmZmZiAwMDAwMDAwMSAwMDAwMDAwMCAwMDAwMDAwMCAwMDAwMDAwMCBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmYycsXG4gIGI6ICc1YWM2MzVkOCBhYTNhOTNlNyBiM2ViYmQ1NSA3Njk4ODZiYyA2NTFkMDZiMCBjYzUzYjBmNiAzYmNlM2MzZSAyN2QyNjA0YicsXG4gIG46ICdmZmZmZmZmZiAwMDAwMDAwMCBmZmZmZmZmZiBmZmZmZmZmZiBiY2U2ZmFhZCBhNzE3OWU4NCBmM2I5Y2FjMiBmYzYzMjU1MScsXG4gIGhhc2g6IGhhc2guc2hhMjU2LFxuICBnUmVkOiBmYWxzZSxcbiAgZzogW1xuICAgICc2YjE3ZDFmMiBlMTJjNDI0NyBmOGJjZTZlNSA2M2E0NDBmMiA3NzAzN2Q4MSAyZGViMzNhMCBmNGExMzk0NSBkODk4YzI5NicsXG4gICAgJzRmZTM0MmUyIGZlMWE3ZjliIDhlZTdlYjRhIDdjMGY5ZTE2IDJiY2UzMzU3IDZiMzE1ZWNlIGNiYjY0MDY4IDM3YmY1MWY1J1xuICBdXG59KTtcblxuZGVmaW5lQ3VydmUoJ3AzODQnLCB7XG4gIHR5cGU6ICdzaG9ydCcsXG4gIHByaW1lOiBudWxsLFxuICBwOiAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgJyArXG4gICAgICdmZmZmZmZmZSBmZmZmZmZmZiAwMDAwMDAwMCAwMDAwMDAwMCBmZmZmZmZmZicsXG4gIGE6ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiAnICtcbiAgICAgJ2ZmZmZmZmZlIGZmZmZmZmZmIDAwMDAwMDAwIDAwMDAwMDAwIGZmZmZmZmZjJyxcbiAgYjogJ2IzMzEyZmE3IGUyM2VlN2U0IDk4OGUwNTZiIGUzZjgyZDE5IDE4MWQ5YzZlIGZlODE0MTEyIDAzMTQwODhmICcgK1xuICAgICAnNTAxMzg3NWEgYzY1NjM5OGQgOGEyZWQxOWQgMmE4NWM4ZWQgZDNlYzJhZWYnLFxuICBuOiAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgYzc2MzRkODEgJyArXG4gICAgICdmNDM3MmRkZiA1ODFhMGRiMiA0OGIwYTc3YSBlY2VjMTk2YSBjY2M1Mjk3MycsXG4gIGhhc2g6IGhhc2guc2hhMzg0LFxuICBnUmVkOiBmYWxzZSxcbiAgZzogW1xuICAgICdhYTg3Y2EyMiBiZThiMDUzNyA4ZWIxYzcxZSBmMzIwYWQ3NCA2ZTFkM2I2MiA4YmE3OWI5OCA1OWY3NDFlMCA4MjU0MmEzOCAnICtcbiAgICAnNTUwMmYyNWQgYmY1NTI5NmMgM2E1NDVlMzggNzI3NjBhYjcnLFxuICAgICczNjE3ZGU0YSA5NjI2MmM2ZiA1ZDllOThiZiA5MjkyZGMyOSBmOGY0MWRiZCAyODlhMTQ3YyBlOWRhMzExMyBiNWYwYjhjMCAnICtcbiAgICAnMGE2MGIxY2UgMWQ3ZTgxOWQgN2E0MzFkN2MgOTBlYTBlNWYnXG4gIF1cbn0pO1xuXG5kZWZpbmVDdXJ2ZSgncDUyMScsIHtcbiAgdHlwZTogJ3Nob3J0JyxcbiAgcHJpbWU6IG51bGwsXG4gIHA6ICcwMDAwMDFmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiAnICtcbiAgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmICcgK1xuICAgICAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYnLFxuICBhOiAnMDAwMDAxZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgJyArXG4gICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiAnICtcbiAgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZjJyxcbiAgYjogJzAwMDAwMDUxIDk1M2ViOTYxIDhlMWM5YTFmIDkyOWEyMWEwIGI2ODU0MGVlIGEyZGE3MjViICcgK1xuICAgICAnOTliMzE1ZjMgYjhiNDg5OTEgOGVmMTA5ZTEgNTYxOTM5NTEgZWM3ZTkzN2IgMTY1MmMwYmQgJyArXG4gICAgICczYmIxYmYwNyAzNTczZGY4OCAzZDJjMzRmMSBlZjQ1MWZkNCA2YjUwM2YwMCcsXG4gIG46ICcwMDAwMDFmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiAnICtcbiAgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZhIDUxODY4NzgzIGJmMmY5NjZiIDdmY2MwMTQ4ICcgK1xuICAgICAnZjcwOWE1ZDAgM2JiNWM5YjggODk5YzQ3YWUgYmI2ZmI3MWUgOTEzODY0MDknLFxuICBoYXNoOiBoYXNoLnNoYTUxMixcbiAgZ1JlZDogZmFsc2UsXG4gIGc6IFtcbiAgICAnMDAwMDAwYzYgODU4ZTA2YjcgMDQwNGU5Y2QgOWUzZWNiNjYgMjM5NWI0NDIgOWM2NDgxMzkgJyArXG4gICAgJzA1M2ZiNTIxIGY4MjhhZjYwIDZiNGQzZGJhIGExNGI1ZTc3IGVmZTc1OTI4IGZlMWRjMTI3ICcgK1xuICAgICdhMmZmYThkZSAzMzQ4YjNjMSA4NTZhNDI5YiBmOTdlN2UzMSBjMmU1YmQ2NicsXG4gICAgJzAwMDAwMTE4IDM5Mjk2YTc4IDlhM2JjMDA0IDVjOGE1ZmI0IDJjN2QxYmQ5IDk4ZjU0NDQ5ICcgK1xuICAgICc1NzliNDQ2OCAxN2FmYmQxNyAyNzNlNjYyYyA5N2VlNzI5OSA1ZWY0MjY0MCBjNTUwYjkwMSAnICtcbiAgICAnM2ZhZDA3NjEgMzUzYzcwODYgYTI3MmMyNDAgODhiZTk0NzYgOWZkMTY2NTAnXG4gIF1cbn0pO1xuXG5kZWZpbmVDdXJ2ZSgnY3VydmUyNTUxOScsIHtcbiAgdHlwZTogJ21vbnQnLFxuICBwcmltZTogJ3AyNTUxOScsXG4gIHA6ICc3ZmZmZmZmZmZmZmZmZmZmIGZmZmZmZmZmZmZmZmZmZmYgZmZmZmZmZmZmZmZmZmZmZiBmZmZmZmZmZmZmZmZmZmVkJyxcbiAgYTogJzc2ZDA2JyxcbiAgYjogJzAnLFxuICBuOiAnMTAwMDAwMDAwMDAwMDAwMCAwMDAwMDAwMDAwMDAwMDAwIDE0ZGVmOWRlYTJmNzljZDYgNTgxMjYzMWE1Y2Y1ZDNlZCcsXG4gIGhhc2g6IGhhc2guc2hhMjU2LFxuICBnUmVkOiBmYWxzZSxcbiAgZzogW1xuICAgICc5J1xuICBdXG59KTtcblxuZGVmaW5lQ3VydmUoJ2VkMjU1MTknLCB7XG4gIHR5cGU6ICdlZHdhcmRzJyxcbiAgcHJpbWU6ICdwMjU1MTknLFxuICBwOiAnN2ZmZmZmZmZmZmZmZmZmZiBmZmZmZmZmZmZmZmZmZmZmIGZmZmZmZmZmZmZmZmZmZmYgZmZmZmZmZmZmZmZmZmZlZCcsXG4gIGE6ICctMScsXG4gIGM6ICcxJyxcbiAgLy8gLTEyMTY2NSAqICgxMjE2NjZeKC0xKSkgKG1vZCBQKVxuICBkOiAnNTIwMzZjZWUyYjZmZmU3MyA4Y2M3NDA3OTc3NzllODk4IDAwNzAwYTRkNDE0MWQ4YWIgNzVlYjRkY2ExMzU5NzhhMycsXG4gIG46ICcxMDAwMDAwMDAwMDAwMDAwIDAwMDAwMDAwMDAwMDAwMDAgMTRkZWY5ZGVhMmY3OWNkNiA1ODEyNjMxYTVjZjVkM2VkJyxcbiAgaGFzaDogaGFzaC5zaGEyNTYsXG4gIGdSZWQ6IGZhbHNlLFxuICBnOiBbXG4gICAgJzIxNjkzNmQzY2Q2ZTUzZmVjMGE0ZTIzMWZkZDZkYzVjNjkyY2M3NjA5NTI1YTdiMmM5NTYyZDYwOGYyNWQ1MWEnLFxuXG4gICAgLy8gNC81XG4gICAgJzY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NTgnXG4gIF1cbn0pO1xuXG52YXIgcHJlO1xudHJ5IHtcbiAgcHJlID0gcmVxdWlyZSgnLi9wcmVjb21wdXRlZC9zZWNwMjU2azEnKTtcbn0gY2F0Y2ggKGUpIHtcbiAgcHJlID0gdW5kZWZpbmVkO1xufVxuXG5kZWZpbmVDdXJ2ZSgnc2VjcDI1NmsxJywge1xuICB0eXBlOiAnc2hvcnQnLFxuICBwcmltZTogJ2syNTYnLFxuICBwOiAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmUgZmZmZmZjMmYnLFxuICBhOiAnMCcsXG4gIGI6ICc3JyxcbiAgbjogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZlIGJhYWVkY2U2IGFmNDhhMDNiIGJmZDI1ZThjIGQwMzY0MTQxJyxcbiAgaDogJzEnLFxuICBoYXNoOiBoYXNoLnNoYTI1NixcblxuICAvLyBQcmVjb21wdXRlZCBlbmRvbW9ycGhpc21cbiAgYmV0YTogJzdhZTk2YTJiNjU3YzA3MTA2ZTY0NDc5ZWFjMzQzNGU5OWNmMDQ5NzUxMmY1ODk5NWMxMzk2YzI4NzE5NTAxZWUnLFxuICBsYW1iZGE6ICc1MzYzYWQ0Y2MwNWMzMGUwYTUyNjFjMDI4ODEyNjQ1YTEyMmUyMmVhMjA4MTY2NzhkZjAyOTY3YzFiMjNiZDcyJyxcbiAgYmFzaXM6IFtcbiAgICB7XG4gICAgICBhOiAnMzA4NmQyMjFhN2Q0NmJjZGU4NmM5MGU0OTI4NGViMTUnLFxuICAgICAgYjogJy1lNDQzN2VkNjAxMGU4ODI4NmY1NDdmYTkwYWJmZTRjMydcbiAgICB9LFxuICAgIHtcbiAgICAgIGE6ICcxMTRjYTUwZjdhOGUyZjNmNjU3YzExMDhkOWQ0NGNmZDgnLFxuICAgICAgYjogJzMwODZkMjIxYTdkNDZiY2RlODZjOTBlNDkyODRlYjE1J1xuICAgIH1cbiAgXSxcblxuICBnUmVkOiBmYWxzZSxcbiAgZzogW1xuICAgICc3OWJlNjY3ZWY5ZGNiYmFjNTVhMDYyOTVjZTg3MGIwNzAyOWJmY2RiMmRjZTI4ZDk1OWYyODE1YjE2ZjgxNzk4JyxcbiAgICAnNDgzYWRhNzcyNmEzYzQ2NTVkYTRmYmZjMGUxMTA4YThmZDE3YjQ0OGE2ODU1NDE5OWM0N2QwOGZmYjEwZDRiOCcsXG4gICAgcHJlXG4gIF1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIGVsbGlwdGljID0gcmVxdWlyZSgnLi4vLi4vZWxsaXB0aWMnKTtcbnZhciB1dGlscyA9IGVsbGlwdGljLnV0aWxzO1xudmFyIGFzc2VydCA9IHV0aWxzLmFzc2VydDtcblxudmFyIEtleVBhaXIgPSByZXF1aXJlKCcuL2tleScpO1xudmFyIFNpZ25hdHVyZSA9IHJlcXVpcmUoJy4vc2lnbmF0dXJlJyk7XG5cbmZ1bmN0aW9uIEVDKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEVDKSlcbiAgICByZXR1cm4gbmV3IEVDKG9wdGlvbnMpO1xuXG4gIC8vIFNob3J0Y3V0IGBlbGxpcHRpYy5lYyhjdXJ2ZS1uYW1lKWBcbiAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJykge1xuICAgIGFzc2VydChlbGxpcHRpYy5jdXJ2ZXMuaGFzT3duUHJvcGVydHkob3B0aW9ucyksICdVbmtub3duIGN1cnZlICcgKyBvcHRpb25zKTtcblxuICAgIG9wdGlvbnMgPSBlbGxpcHRpYy5jdXJ2ZXNbb3B0aW9uc107XG4gIH1cblxuICAvLyBTaG9ydGN1dCBmb3IgYGVsbGlwdGljLmVjKGVsbGlwdGljLmN1cnZlcy5jdXJ2ZU5hbWUpYFxuICBpZiAob3B0aW9ucyBpbnN0YW5jZW9mIGVsbGlwdGljLmN1cnZlcy5QcmVzZXRDdXJ2ZSlcbiAgICBvcHRpb25zID0geyBjdXJ2ZTogb3B0aW9ucyB9O1xuXG4gIHRoaXMuY3VydmUgPSBvcHRpb25zLmN1cnZlLmN1cnZlO1xuICB0aGlzLm4gPSB0aGlzLmN1cnZlLm47XG4gIHRoaXMubmggPSB0aGlzLm4udXNocm4oMSk7XG4gIHRoaXMuZyA9IHRoaXMuY3VydmUuZztcblxuICAvLyBQb2ludCBvbiBjdXJ2ZVxuICB0aGlzLmcgPSBvcHRpb25zLmN1cnZlLmc7XG4gIHRoaXMuZy5wcmVjb21wdXRlKG9wdGlvbnMuY3VydmUubi5iaXRMZW5ndGgoKSArIDEpO1xuXG4gIC8vIEhhc2ggZm9yIGZ1bmN0aW9uIGZvciBEUkJHXG4gIHRoaXMuaGFzaCA9IG9wdGlvbnMuaGFzaCB8fCBvcHRpb25zLmN1cnZlLmhhc2g7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEVDO1xuXG5FQy5wcm90b3R5cGUua2V5UGFpciA9IGZ1bmN0aW9uIGtleVBhaXIob3B0aW9ucykge1xuICByZXR1cm4gbmV3IEtleVBhaXIodGhpcywgb3B0aW9ucyk7XG59O1xuXG5FQy5wcm90b3R5cGUua2V5RnJvbVByaXZhdGUgPSBmdW5jdGlvbiBrZXlGcm9tUHJpdmF0ZShwcml2LCBlbmMpIHtcbiAgcmV0dXJuIEtleVBhaXIuZnJvbVByaXZhdGUodGhpcywgcHJpdiwgZW5jKTtcbn07XG5cbkVDLnByb3RvdHlwZS5rZXlGcm9tUHVibGljID0gZnVuY3Rpb24ga2V5RnJvbVB1YmxpYyhwdWIsIGVuYykge1xuICByZXR1cm4gS2V5UGFpci5mcm9tUHVibGljKHRoaXMsIHB1YiwgZW5jKTtcbn07XG5cbkVDLnByb3RvdHlwZS5nZW5LZXlQYWlyID0gZnVuY3Rpb24gZ2VuS2V5UGFpcihvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucylcbiAgICBvcHRpb25zID0ge307XG5cbiAgLy8gSW5zdGFudGlhdGUgSG1hY19EUkJHXG4gIHZhciBkcmJnID0gbmV3IGVsbGlwdGljLmhtYWNEUkJHKHtcbiAgICBoYXNoOiB0aGlzLmhhc2gsXG4gICAgcGVyczogb3B0aW9ucy5wZXJzLFxuICAgIGVudHJvcHk6IG9wdGlvbnMuZW50cm9weSB8fCBlbGxpcHRpYy5yYW5kKHRoaXMuaGFzaC5obWFjU3RyZW5ndGgpLFxuICAgIG5vbmNlOiB0aGlzLm4udG9BcnJheSgpXG4gIH0pO1xuXG4gIHZhciBieXRlcyA9IHRoaXMubi5ieXRlTGVuZ3RoKCk7XG4gIHZhciBuczIgPSB0aGlzLm4uc3ViKG5ldyBCTigyKSk7XG4gIGRvIHtcbiAgICB2YXIgcHJpdiA9IG5ldyBCTihkcmJnLmdlbmVyYXRlKGJ5dGVzKSk7XG4gICAgaWYgKHByaXYuY21wKG5zMikgPiAwKVxuICAgICAgY29udGludWU7XG5cbiAgICBwcml2LmlhZGRuKDEpO1xuICAgIHJldHVybiB0aGlzLmtleUZyb21Qcml2YXRlKHByaXYpO1xuICB9IHdoaWxlICh0cnVlKTtcbn07XG5cbkVDLnByb3RvdHlwZS5fdHJ1bmNhdGVUb04gPSBmdW5jdGlvbiB0cnVuY2F0ZVRvTihtc2csIHRydW5jT25seSkge1xuICB2YXIgZGVsdGEgPSBtc2cuYnl0ZUxlbmd0aCgpICogOCAtIHRoaXMubi5iaXRMZW5ndGgoKTtcbiAgaWYgKGRlbHRhID4gMClcbiAgICBtc2cgPSBtc2cudXNocm4oZGVsdGEpO1xuICBpZiAoIXRydW5jT25seSAmJiBtc2cuY21wKHRoaXMubikgPj0gMClcbiAgICByZXR1cm4gbXNnLnN1Yih0aGlzLm4pO1xuICBlbHNlXG4gICAgcmV0dXJuIG1zZztcbn07XG5cbkVDLnByb3RvdHlwZS5zaWduID0gZnVuY3Rpb24gc2lnbihtc2csIGtleSwgZW5jLCBvcHRpb25zKSB7XG4gIGlmICh0eXBlb2YgZW5jID09PSAnb2JqZWN0Jykge1xuICAgIG9wdGlvbnMgPSBlbmM7XG4gICAgZW5jID0gbnVsbDtcbiAgfVxuICBpZiAoIW9wdGlvbnMpXG4gICAgb3B0aW9ucyA9IHt9O1xuXG4gIGtleSA9IHRoaXMua2V5RnJvbVByaXZhdGUoa2V5LCBlbmMpO1xuICBtc2cgPSB0aGlzLl90cnVuY2F0ZVRvTihuZXcgQk4obXNnLCAxNikpO1xuXG4gIC8vIFplcm8tZXh0ZW5kIGtleSB0byBwcm92aWRlIGVub3VnaCBlbnRyb3B5XG4gIHZhciBieXRlcyA9IHRoaXMubi5ieXRlTGVuZ3RoKCk7XG4gIHZhciBia2V5ID0ga2V5LmdldFByaXZhdGUoKS50b0FycmF5KCdiZScsIGJ5dGVzKTtcblxuICAvLyBaZXJvLWV4dGVuZCBub25jZSB0byBoYXZlIHRoZSBzYW1lIGJ5dGUgc2l6ZSBhcyBOXG4gIHZhciBub25jZSA9IG1zZy50b0FycmF5KCdiZScsIGJ5dGVzKTtcblxuICAvLyBJbnN0YW50aWF0ZSBIbWFjX0RSQkdcbiAgdmFyIGRyYmcgPSBuZXcgZWxsaXB0aWMuaG1hY0RSQkcoe1xuICAgIGhhc2g6IHRoaXMuaGFzaCxcbiAgICBlbnRyb3B5OiBia2V5LFxuICAgIG5vbmNlOiBub25jZSxcbiAgICBwZXJzOiBvcHRpb25zLnBlcnMsXG4gICAgcGVyc0VuYzogb3B0aW9ucy5wZXJzRW5jXG4gIH0pO1xuXG4gIC8vIE51bWJlciBvZiBieXRlcyB0byBnZW5lcmF0ZVxuICB2YXIgbnMxID0gdGhpcy5uLnN1YihuZXcgQk4oMSkpO1xuXG4gIGZvciAodmFyIGl0ZXIgPSAwOyB0cnVlOyBpdGVyKyspIHtcbiAgICB2YXIgayA9IG9wdGlvbnMuayA/XG4gICAgICAgIG9wdGlvbnMuayhpdGVyKSA6XG4gICAgICAgIG5ldyBCTihkcmJnLmdlbmVyYXRlKHRoaXMubi5ieXRlTGVuZ3RoKCkpKTtcbiAgICBrID0gdGhpcy5fdHJ1bmNhdGVUb04oaywgdHJ1ZSk7XG4gICAgaWYgKGsuY21wbigxKSA8PSAwIHx8IGsuY21wKG5zMSkgPj0gMClcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgdmFyIGtwID0gdGhpcy5nLm11bChrKTtcbiAgICBpZiAoa3AuaXNJbmZpbml0eSgpKVxuICAgICAgY29udGludWU7XG5cbiAgICB2YXIga3BYID0ga3AuZ2V0WCgpO1xuICAgIHZhciByID0ga3BYLnVtb2QodGhpcy5uKTtcbiAgICBpZiAoci5jbXBuKDApID09PSAwKVxuICAgICAgY29udGludWU7XG5cbiAgICB2YXIgcyA9IGsuaW52bSh0aGlzLm4pLm11bChyLm11bChrZXkuZ2V0UHJpdmF0ZSgpKS5pYWRkKG1zZykpO1xuICAgIHMgPSBzLnVtb2QodGhpcy5uKTtcbiAgICBpZiAocy5jbXBuKDApID09PSAwKVxuICAgICAgY29udGludWU7XG5cbiAgICB2YXIgcmVjb3ZlcnlQYXJhbSA9IChrcC5nZXRZKCkuaXNPZGQoKSA/IDEgOiAwKSB8XG4gICAgICAgICAgICAgICAgICAgICAgICAoa3BYLmNtcChyKSAhPT0gMCA/IDIgOiAwKTtcblxuICAgIC8vIFVzZSBjb21wbGVtZW50IG9mIGBzYCwgaWYgaXQgaXMgPiBgbiAvIDJgXG4gICAgaWYgKG9wdGlvbnMuY2Fub25pY2FsICYmIHMuY21wKHRoaXMubmgpID4gMCkge1xuICAgICAgcyA9IHRoaXMubi5zdWIocyk7XG4gICAgICByZWNvdmVyeVBhcmFtIF49IDE7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBTaWduYXR1cmUoeyByOiByLCBzOiBzLCByZWNvdmVyeVBhcmFtOiByZWNvdmVyeVBhcmFtIH0pO1xuICB9XG59O1xuXG5FQy5wcm90b3R5cGUudmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1zZywgc2lnbmF0dXJlLCBrZXksIGVuYykge1xuICBtc2cgPSB0aGlzLl90cnVuY2F0ZVRvTihuZXcgQk4obXNnLCAxNikpO1xuICBrZXkgPSB0aGlzLmtleUZyb21QdWJsaWMoa2V5LCBlbmMpO1xuICBzaWduYXR1cmUgPSBuZXcgU2lnbmF0dXJlKHNpZ25hdHVyZSwgJ2hleCcpO1xuXG4gIC8vIFBlcmZvcm0gcHJpbWl0aXZlIHZhbHVlcyB2YWxpZGF0aW9uXG4gIHZhciByID0gc2lnbmF0dXJlLnI7XG4gIHZhciBzID0gc2lnbmF0dXJlLnM7XG4gIGlmIChyLmNtcG4oMSkgPCAwIHx8IHIuY21wKHRoaXMubikgPj0gMClcbiAgICByZXR1cm4gZmFsc2U7XG4gIGlmIChzLmNtcG4oMSkgPCAwIHx8IHMuY21wKHRoaXMubikgPj0gMClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgLy8gVmFsaWRhdGUgc2lnbmF0dXJlXG4gIHZhciBzaW52ID0gcy5pbnZtKHRoaXMubik7XG4gIHZhciB1MSA9IHNpbnYubXVsKG1zZykudW1vZCh0aGlzLm4pO1xuICB2YXIgdTIgPSBzaW52Lm11bChyKS51bW9kKHRoaXMubik7XG5cbiAgdmFyIHAgPSB0aGlzLmcubXVsQWRkKHUxLCBrZXkuZ2V0UHVibGljKCksIHUyKTtcbiAgaWYgKHAuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiBmYWxzZTtcblxuICByZXR1cm4gcC5nZXRYKCkudW1vZCh0aGlzLm4pLmNtcChyKSA9PT0gMDtcbn07XG5cbkVDLnByb3RvdHlwZS5yZWNvdmVyUHViS2V5ID0gZnVuY3Rpb24obXNnLCBzaWduYXR1cmUsIGosIGVuYykge1xuICBhc3NlcnQoKDMgJiBqKSA9PT0gaiwgJ1RoZSByZWNvdmVyeSBwYXJhbSBpcyBtb3JlIHRoYW4gdHdvIGJpdHMnKTtcbiAgc2lnbmF0dXJlID0gbmV3IFNpZ25hdHVyZShzaWduYXR1cmUsIGVuYyk7XG5cbiAgdmFyIG4gPSB0aGlzLm47XG4gIHZhciBlID0gbmV3IEJOKG1zZyk7XG4gIHZhciByID0gc2lnbmF0dXJlLnI7XG4gIHZhciBzID0gc2lnbmF0dXJlLnM7XG5cbiAgLy8gQSBzZXQgTFNCIHNpZ25pZmllcyB0aGF0IHRoZSB5LWNvb3JkaW5hdGUgaXMgb2RkXG4gIHZhciBpc1lPZGQgPSBqICYgMTtcbiAgdmFyIGlzU2Vjb25kS2V5ID0gaiA+PiAxO1xuICBpZiAoci5jbXAodGhpcy5jdXJ2ZS5wLnVtb2QodGhpcy5jdXJ2ZS5uKSkgPj0gMCAmJiBpc1NlY29uZEtleSlcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBmaW5kIHNlbmNvbmQga2V5IGNhbmRpbmF0ZScpO1xuXG4gIC8vIDEuMS4gTGV0IHggPSByICsgam4uXG4gIGlmIChpc1NlY29uZEtleSlcbiAgICByID0gdGhpcy5jdXJ2ZS5wb2ludEZyb21YKHIuYWRkKHRoaXMuY3VydmUubiksIGlzWU9kZCk7XG4gIGVsc2VcbiAgICByID0gdGhpcy5jdXJ2ZS5wb2ludEZyb21YKHIsIGlzWU9kZCk7XG5cbiAgdmFyIGVOZWcgPSBuLnN1YihlKTtcblxuICAvLyAxLjYuMSBDb21wdXRlIFEgPSByXi0xIChzUiAtICBlRylcbiAgLy8gICAgICAgICAgICAgICBRID0gcl4tMSAoc1IgKyAtZUcpXG4gIHZhciBySW52ID0gc2lnbmF0dXJlLnIuaW52bShuKTtcbiAgcmV0dXJuIHRoaXMuZy5tdWxBZGQoZU5lZywgciwgcykubXVsKHJJbnYpO1xufTtcblxuRUMucHJvdG90eXBlLmdldEtleVJlY292ZXJ5UGFyYW0gPSBmdW5jdGlvbihlLCBzaWduYXR1cmUsIFEsIGVuYykge1xuICBzaWduYXR1cmUgPSBuZXcgU2lnbmF0dXJlKHNpZ25hdHVyZSwgZW5jKTtcbiAgaWYgKHNpZ25hdHVyZS5yZWNvdmVyeVBhcmFtICE9PSBudWxsKVxuICAgIHJldHVybiBzaWduYXR1cmUucmVjb3ZlcnlQYXJhbTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIHZhciBRcHJpbWU7XG4gICAgdHJ5IHtcbiAgICAgIFFwcmltZSA9IHRoaXMucmVjb3ZlclB1YktleShlLCBzaWduYXR1cmUsIGkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChRcHJpbWUuZXEoUSkpXG4gICAgICByZXR1cm4gaTtcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBmaW5kIHZhbGlkIHJlY292ZXJ5IGZhY3RvcicpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcblxuZnVuY3Rpb24gS2V5UGFpcihlYywgb3B0aW9ucykge1xuICB0aGlzLmVjID0gZWM7XG4gIHRoaXMucHJpdiA9IG51bGw7XG4gIHRoaXMucHViID0gbnVsbDtcblxuICAvLyBLZXlQYWlyKGVjLCB7IHByaXY6IC4uLiwgcHViOiAuLi4gfSlcbiAgaWYgKG9wdGlvbnMucHJpdilcbiAgICB0aGlzLl9pbXBvcnRQcml2YXRlKG9wdGlvbnMucHJpdiwgb3B0aW9ucy5wcml2RW5jKTtcbiAgaWYgKG9wdGlvbnMucHViKVxuICAgIHRoaXMuX2ltcG9ydFB1YmxpYyhvcHRpb25zLnB1Yiwgb3B0aW9ucy5wdWJFbmMpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBLZXlQYWlyO1xuXG5LZXlQYWlyLmZyb21QdWJsaWMgPSBmdW5jdGlvbiBmcm9tUHVibGljKGVjLCBwdWIsIGVuYykge1xuICBpZiAocHViIGluc3RhbmNlb2YgS2V5UGFpcilcbiAgICByZXR1cm4gcHViO1xuXG4gIHJldHVybiBuZXcgS2V5UGFpcihlYywge1xuICAgIHB1YjogcHViLFxuICAgIHB1YkVuYzogZW5jXG4gIH0pO1xufTtcblxuS2V5UGFpci5mcm9tUHJpdmF0ZSA9IGZ1bmN0aW9uIGZyb21Qcml2YXRlKGVjLCBwcml2LCBlbmMpIHtcbiAgaWYgKHByaXYgaW5zdGFuY2VvZiBLZXlQYWlyKVxuICAgIHJldHVybiBwcml2O1xuXG4gIHJldHVybiBuZXcgS2V5UGFpcihlYywge1xuICAgIHByaXY6IHByaXYsXG4gICAgcHJpdkVuYzogZW5jXG4gIH0pO1xufTtcblxuS2V5UGFpci5wcm90b3R5cGUudmFsaWRhdGUgPSBmdW5jdGlvbiB2YWxpZGF0ZSgpIHtcbiAgdmFyIHB1YiA9IHRoaXMuZ2V0UHVibGljKCk7XG5cbiAgaWYgKHB1Yi5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHsgcmVzdWx0OiBmYWxzZSwgcmVhc29uOiAnSW52YWxpZCBwdWJsaWMga2V5JyB9O1xuICBpZiAoIXB1Yi52YWxpZGF0ZSgpKVxuICAgIHJldHVybiB7IHJlc3VsdDogZmFsc2UsIHJlYXNvbjogJ1B1YmxpYyBrZXkgaXMgbm90IGEgcG9pbnQnIH07XG4gIGlmICghcHViLm11bCh0aGlzLmVjLmN1cnZlLm4pLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCByZWFzb246ICdQdWJsaWMga2V5ICogTiAhPSBPJyB9O1xuXG4gIHJldHVybiB7IHJlc3VsdDogdHJ1ZSwgcmVhc29uOiBudWxsIH07XG59O1xuXG5LZXlQYWlyLnByb3RvdHlwZS5nZXRQdWJsaWMgPSBmdW5jdGlvbiBnZXRQdWJsaWMoY29tcGFjdCwgZW5jKSB7XG4gIC8vIGNvbXBhY3QgaXMgb3B0aW9uYWwgYXJndW1lbnRcbiAgaWYgKHR5cGVvZiBjb21wYWN0ID09PSAnc3RyaW5nJykge1xuICAgIGVuYyA9IGNvbXBhY3Q7XG4gICAgY29tcGFjdCA9IG51bGw7XG4gIH1cblxuICBpZiAoIXRoaXMucHViKVxuICAgIHRoaXMucHViID0gdGhpcy5lYy5nLm11bCh0aGlzLnByaXYpO1xuXG4gIGlmICghZW5jKVxuICAgIHJldHVybiB0aGlzLnB1YjtcblxuICByZXR1cm4gdGhpcy5wdWIuZW5jb2RlKGVuYywgY29tcGFjdCk7XG59O1xuXG5LZXlQYWlyLnByb3RvdHlwZS5nZXRQcml2YXRlID0gZnVuY3Rpb24gZ2V0UHJpdmF0ZShlbmMpIHtcbiAgaWYgKGVuYyA9PT0gJ2hleCcpXG4gICAgcmV0dXJuIHRoaXMucHJpdi50b1N0cmluZygxNiwgMik7XG4gIGVsc2VcbiAgICByZXR1cm4gdGhpcy5wcml2O1xufTtcblxuS2V5UGFpci5wcm90b3R5cGUuX2ltcG9ydFByaXZhdGUgPSBmdW5jdGlvbiBfaW1wb3J0UHJpdmF0ZShrZXksIGVuYykge1xuICB0aGlzLnByaXYgPSBuZXcgQk4oa2V5LCBlbmMgfHwgMTYpO1xuXG4gIC8vIEVuc3VyZSB0aGF0IHRoZSBwcml2IHdvbid0IGJlIGJpZ2dlciB0aGFuIG4sIG90aGVyd2lzZSB3ZSBtYXkgZmFpbFxuICAvLyBpbiBmaXhlZCBtdWx0aXBsaWNhdGlvbiBtZXRob2RcbiAgdGhpcy5wcml2ID0gdGhpcy5wcml2LnVtb2QodGhpcy5lYy5jdXJ2ZS5uKTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLl9pbXBvcnRQdWJsaWMgPSBmdW5jdGlvbiBfaW1wb3J0UHVibGljKGtleSwgZW5jKSB7XG4gIGlmIChrZXkueCB8fCBrZXkueSkge1xuICAgIHRoaXMucHViID0gdGhpcy5lYy5jdXJ2ZS5wb2ludChrZXkueCwga2V5LnkpO1xuICAgIHJldHVybjtcbiAgfVxuICB0aGlzLnB1YiA9IHRoaXMuZWMuY3VydmUuZGVjb2RlUG9pbnQoa2V5LCBlbmMpO1xufTtcblxuLy8gRUNESFxuS2V5UGFpci5wcm90b3R5cGUuZGVyaXZlID0gZnVuY3Rpb24gZGVyaXZlKHB1Yikge1xuICByZXR1cm4gcHViLm11bCh0aGlzLnByaXYpLmdldFgoKTtcbn07XG5cbi8vIEVDRFNBXG5LZXlQYWlyLnByb3RvdHlwZS5zaWduID0gZnVuY3Rpb24gc2lnbihtc2csIGVuYywgb3B0aW9ucykge1xuICByZXR1cm4gdGhpcy5lYy5zaWduKG1zZywgdGhpcywgZW5jLCBvcHRpb25zKTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtc2csIHNpZ25hdHVyZSkge1xuICByZXR1cm4gdGhpcy5lYy52ZXJpZnkobXNnLCBzaWduYXR1cmUsIHRoaXMpO1xufTtcblxuS2V5UGFpci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QoKSB7XG4gIHJldHVybiAnPEtleSBwcml2OiAnICsgKHRoaXMucHJpdiAmJiB0aGlzLnByaXYudG9TdHJpbmcoMTYsIDIpKSArXG4gICAgICAgICAnIHB1YjogJyArICh0aGlzLnB1YiAmJiB0aGlzLnB1Yi5pbnNwZWN0KCkpICsgJyA+Jztcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG5cbnZhciBlbGxpcHRpYyA9IHJlcXVpcmUoJy4uLy4uL2VsbGlwdGljJyk7XG52YXIgdXRpbHMgPSBlbGxpcHRpYy51dGlscztcbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG5cbmZ1bmN0aW9uIFNpZ25hdHVyZShvcHRpb25zLCBlbmMpIHtcbiAgaWYgKG9wdGlvbnMgaW5zdGFuY2VvZiBTaWduYXR1cmUpXG4gICAgcmV0dXJuIG9wdGlvbnM7XG5cbiAgaWYgKHRoaXMuX2ltcG9ydERFUihvcHRpb25zLCBlbmMpKVxuICAgIHJldHVybjtcblxuICBhc3NlcnQob3B0aW9ucy5yICYmIG9wdGlvbnMucywgJ1NpZ25hdHVyZSB3aXRob3V0IHIgb3IgcycpO1xuICB0aGlzLnIgPSBuZXcgQk4ob3B0aW9ucy5yLCAxNik7XG4gIHRoaXMucyA9IG5ldyBCTihvcHRpb25zLnMsIDE2KTtcbiAgaWYgKG9wdGlvbnMucmVjb3ZlcnlQYXJhbSA9PT0gdW5kZWZpbmVkKVxuICAgIHRoaXMucmVjb3ZlcnlQYXJhbSA9IG51bGw7XG4gIGVsc2VcbiAgICB0aGlzLnJlY292ZXJ5UGFyYW0gPSBvcHRpb25zLnJlY292ZXJ5UGFyYW07XG59XG5tb2R1bGUuZXhwb3J0cyA9IFNpZ25hdHVyZTtcblxuZnVuY3Rpb24gUG9zaXRpb24oKSB7XG4gIHRoaXMucGxhY2UgPSAwO1xufVxuXG5mdW5jdGlvbiBnZXRMZW5ndGgoYnVmLCBwKSB7XG4gIHZhciBpbml0aWFsID0gYnVmW3AucGxhY2UrK107XG4gIGlmICghKGluaXRpYWwgJiAweDgwKSkge1xuICAgIHJldHVybiBpbml0aWFsO1xuICB9XG4gIHZhciBvY3RldExlbiA9IGluaXRpYWwgJiAweGY7XG4gIHZhciB2YWwgPSAwO1xuICBmb3IgKHZhciBpID0gMCwgb2ZmID0gcC5wbGFjZTsgaSA8IG9jdGV0TGVuOyBpKyssIG9mZisrKSB7XG4gICAgdmFsIDw8PSA4O1xuICAgIHZhbCB8PSBidWZbb2ZmXTtcbiAgfVxuICBwLnBsYWNlID0gb2ZmO1xuICByZXR1cm4gdmFsO1xufVxuXG5mdW5jdGlvbiBybVBhZGRpbmcoYnVmKSB7XG4gIHZhciBpID0gMDtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGggLSAxO1xuICB3aGlsZSAoIWJ1ZltpXSAmJiAhKGJ1ZltpICsgMV0gJiAweDgwKSAmJiBpIDwgbGVuKSB7XG4gICAgaSsrO1xuICB9XG4gIGlmIChpID09PSAwKSB7XG4gICAgcmV0dXJuIGJ1ZjtcbiAgfVxuICByZXR1cm4gYnVmLnNsaWNlKGkpO1xufVxuXG5TaWduYXR1cmUucHJvdG90eXBlLl9pbXBvcnRERVIgPSBmdW5jdGlvbiBfaW1wb3J0REVSKGRhdGEsIGVuYykge1xuICBkYXRhID0gdXRpbHMudG9BcnJheShkYXRhLCBlbmMpO1xuICB2YXIgcCA9IG5ldyBQb3NpdGlvbigpO1xuICBpZiAoZGF0YVtwLnBsYWNlKytdICE9PSAweDMwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBsZW4gPSBnZXRMZW5ndGgoZGF0YSwgcCk7XG4gIGlmICgobGVuICsgcC5wbGFjZSkgIT09IGRhdGEubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChkYXRhW3AucGxhY2UrK10gIT09IDB4MDIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHJsZW4gPSBnZXRMZW5ndGgoZGF0YSwgcCk7XG4gIHZhciByID0gZGF0YS5zbGljZShwLnBsYWNlLCBybGVuICsgcC5wbGFjZSk7XG4gIHAucGxhY2UgKz0gcmxlbjtcbiAgaWYgKGRhdGFbcC5wbGFjZSsrXSAhPT0gMHgwMikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgc2xlbiA9IGdldExlbmd0aChkYXRhLCBwKTtcbiAgaWYgKGRhdGEubGVuZ3RoICE9PSBzbGVuICsgcC5wbGFjZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgcyA9IGRhdGEuc2xpY2UocC5wbGFjZSwgc2xlbiArIHAucGxhY2UpO1xuICBpZiAoclswXSA9PT0gMCAmJiAoclsxXSAmIDB4ODApKSB7XG4gICAgciA9IHIuc2xpY2UoMSk7XG4gIH1cbiAgaWYgKHNbMF0gPT09IDAgJiYgKHNbMV0gJiAweDgwKSkge1xuICAgIHMgPSBzLnNsaWNlKDEpO1xuICB9XG5cbiAgdGhpcy5yID0gbmV3IEJOKHIpO1xuICB0aGlzLnMgPSBuZXcgQk4ocyk7XG4gIHRoaXMucmVjb3ZlcnlQYXJhbSA9IG51bGw7XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5mdW5jdGlvbiBjb25zdHJ1Y3RMZW5ndGgoYXJyLCBsZW4pIHtcbiAgaWYgKGxlbiA8IDB4ODApIHtcbiAgICBhcnIucHVzaChsZW4pO1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgb2N0ZXRzID0gMSArIChNYXRoLmxvZyhsZW4pIC8gTWF0aC5MTjIgPj4+IDMpO1xuICBhcnIucHVzaChvY3RldHMgfCAweDgwKTtcbiAgd2hpbGUgKC0tb2N0ZXRzKSB7XG4gICAgYXJyLnB1c2goKGxlbiA+Pj4gKG9jdGV0cyA8PCAzKSkgJiAweGZmKTtcbiAgfVxuICBhcnIucHVzaChsZW4pO1xufVxuXG5TaWduYXR1cmUucHJvdG90eXBlLnRvREVSID0gZnVuY3Rpb24gdG9ERVIoZW5jKSB7XG4gIHZhciByID0gdGhpcy5yLnRvQXJyYXkoKTtcbiAgdmFyIHMgPSB0aGlzLnMudG9BcnJheSgpO1xuXG4gIC8vIFBhZCB2YWx1ZXNcbiAgaWYgKHJbMF0gJiAweDgwKVxuICAgIHIgPSBbIDAgXS5jb25jYXQocik7XG4gIC8vIFBhZCB2YWx1ZXNcbiAgaWYgKHNbMF0gJiAweDgwKVxuICAgIHMgPSBbIDAgXS5jb25jYXQocyk7XG5cbiAgciA9IHJtUGFkZGluZyhyKTtcbiAgcyA9IHJtUGFkZGluZyhzKTtcblxuICB3aGlsZSAoIXNbMF0gJiYgIShzWzFdICYgMHg4MCkpIHtcbiAgICBzID0gcy5zbGljZSgxKTtcbiAgfVxuICB2YXIgYXJyID0gWyAweDAyIF07XG4gIGNvbnN0cnVjdExlbmd0aChhcnIsIHIubGVuZ3RoKTtcbiAgYXJyID0gYXJyLmNvbmNhdChyKTtcbiAgYXJyLnB1c2goMHgwMik7XG4gIGNvbnN0cnVjdExlbmd0aChhcnIsIHMubGVuZ3RoKTtcbiAgdmFyIGJhY2tIYWxmID0gYXJyLmNvbmNhdChzKTtcbiAgdmFyIHJlcyA9IFsgMHgzMCBdO1xuICBjb25zdHJ1Y3RMZW5ndGgocmVzLCBiYWNrSGFsZi5sZW5ndGgpO1xuICByZXMgPSByZXMuY29uY2F0KGJhY2tIYWxmKTtcbiAgcmV0dXJuIHV0aWxzLmVuY29kZShyZXMsIGVuYyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzaCA9IHJlcXVpcmUoJ2hhc2guanMnKTtcbnZhciBlbGxpcHRpYyA9IHJlcXVpcmUoJy4uLy4uL2VsbGlwdGljJyk7XG52YXIgdXRpbHMgPSBlbGxpcHRpYy51dGlscztcbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG52YXIgcGFyc2VCeXRlcyA9IHV0aWxzLnBhcnNlQnl0ZXM7XG52YXIgS2V5UGFpciA9IHJlcXVpcmUoJy4va2V5Jyk7XG52YXIgU2lnbmF0dXJlID0gcmVxdWlyZSgnLi9zaWduYXR1cmUnKTtcblxuZnVuY3Rpb24gRUREU0EoY3VydmUpIHtcbiAgYXNzZXJ0KGN1cnZlID09PSAnZWQyNTUxOScsICdvbmx5IHRlc3RlZCB3aXRoIGVkMjU1MTkgc28gZmFyJyk7XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEVERFNBKSlcbiAgICByZXR1cm4gbmV3IEVERFNBKGN1cnZlKTtcblxuICB2YXIgY3VydmUgPSBlbGxpcHRpYy5jdXJ2ZXNbY3VydmVdLmN1cnZlO1xuICB0aGlzLmN1cnZlID0gY3VydmU7XG4gIHRoaXMuZyA9IGN1cnZlLmc7XG4gIHRoaXMuZy5wcmVjb21wdXRlKGN1cnZlLm4uYml0TGVuZ3RoKCkgKyAxKTtcblxuICB0aGlzLnBvaW50Q2xhc3MgPSBjdXJ2ZS5wb2ludCgpLmNvbnN0cnVjdG9yO1xuICB0aGlzLmVuY29kaW5nTGVuZ3RoID0gTWF0aC5jZWlsKGN1cnZlLm4uYml0TGVuZ3RoKCkgLyA4KTtcbiAgdGhpcy5oYXNoID0gaGFzaC5zaGE1MTI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gRUREU0E7XG5cbi8qKlxuKiBAcGFyYW0ge0FycmF5fFN0cmluZ30gbWVzc2FnZSAtIG1lc3NhZ2UgYnl0ZXNcbiogQHBhcmFtIHtBcnJheXxTdHJpbmd8S2V5UGFpcn0gc2VjcmV0IC0gc2VjcmV0IGJ5dGVzIG9yIGEga2V5cGFpclxuKiBAcmV0dXJucyB7U2lnbmF0dXJlfSAtIHNpZ25hdHVyZVxuKi9cbkVERFNBLnByb3RvdHlwZS5zaWduID0gZnVuY3Rpb24gc2lnbihtZXNzYWdlLCBzZWNyZXQpIHtcbiAgbWVzc2FnZSA9IHBhcnNlQnl0ZXMobWVzc2FnZSk7XG4gIHZhciBrZXkgPSB0aGlzLmtleUZyb21TZWNyZXQoc2VjcmV0KTtcbiAgdmFyIHIgPSB0aGlzLmhhc2hJbnQoa2V5Lm1lc3NhZ2VQcmVmaXgoKSwgbWVzc2FnZSk7XG4gIHZhciBSID0gdGhpcy5nLm11bChyKTtcbiAgdmFyIFJlbmNvZGVkID0gdGhpcy5lbmNvZGVQb2ludChSKTtcbiAgdmFyIHNfID0gdGhpcy5oYXNoSW50KFJlbmNvZGVkLCBrZXkucHViQnl0ZXMoKSwgbWVzc2FnZSlcbiAgICAgICAgICAgICAgIC5tdWwoa2V5LnByaXYoKSk7XG4gIHZhciBTID0gci5hZGQoc18pLnVtb2QodGhpcy5jdXJ2ZS5uKTtcbiAgcmV0dXJuIHRoaXMubWFrZVNpZ25hdHVyZSh7IFI6IFIsIFM6IFMsIFJlbmNvZGVkOiBSZW5jb2RlZCB9KTtcbn07XG5cbi8qKlxuKiBAcGFyYW0ge0FycmF5fSBtZXNzYWdlIC0gbWVzc2FnZSBieXRlc1xuKiBAcGFyYW0ge0FycmF5fFN0cmluZ3xTaWduYXR1cmV9IHNpZyAtIHNpZyBieXRlc1xuKiBAcGFyYW0ge0FycmF5fFN0cmluZ3xQb2ludHxLZXlQYWlyfSBwdWIgLSBwdWJsaWMga2V5XG4qIEByZXR1cm5zIHtCb29sZWFufSAtIHRydWUgaWYgcHVibGljIGtleSBtYXRjaGVzIHNpZyBvZiBtZXNzYWdlXG4qL1xuRUREU0EucHJvdG90eXBlLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlLCBzaWcsIHB1Yikge1xuICBtZXNzYWdlID0gcGFyc2VCeXRlcyhtZXNzYWdlKTtcbiAgc2lnID0gdGhpcy5tYWtlU2lnbmF0dXJlKHNpZyk7XG4gIHZhciBrZXkgPSB0aGlzLmtleUZyb21QdWJsaWMocHViKTtcbiAgdmFyIGggPSB0aGlzLmhhc2hJbnQoc2lnLlJlbmNvZGVkKCksIGtleS5wdWJCeXRlcygpLCBtZXNzYWdlKTtcbiAgdmFyIFNHID0gdGhpcy5nLm11bChzaWcuUygpKTtcbiAgdmFyIFJwbHVzQWggPSBzaWcuUigpLmFkZChrZXkucHViKCkubXVsKGgpKTtcbiAgcmV0dXJuIFJwbHVzQWguZXEoU0cpO1xufTtcblxuRUREU0EucHJvdG90eXBlLmhhc2hJbnQgPSBmdW5jdGlvbiBoYXNoSW50KCkge1xuICB2YXIgaGFzaCA9IHRoaXMuaGFzaCgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcbiAgICBoYXNoLnVwZGF0ZShhcmd1bWVudHNbaV0pO1xuICByZXR1cm4gdXRpbHMuaW50RnJvbUxFKGhhc2guZGlnZXN0KCkpLnVtb2QodGhpcy5jdXJ2ZS5uKTtcbn07XG5cbkVERFNBLnByb3RvdHlwZS5rZXlGcm9tUHVibGljID0gZnVuY3Rpb24ga2V5RnJvbVB1YmxpYyhwdWIpIHtcbiAgcmV0dXJuIEtleVBhaXIuZnJvbVB1YmxpYyh0aGlzLCBwdWIpO1xufTtcblxuRUREU0EucHJvdG90eXBlLmtleUZyb21TZWNyZXQgPSBmdW5jdGlvbiBrZXlGcm9tU2VjcmV0KHNlY3JldCkge1xuICByZXR1cm4gS2V5UGFpci5mcm9tU2VjcmV0KHRoaXMsIHNlY3JldCk7XG59O1xuXG5FRERTQS5wcm90b3R5cGUubWFrZVNpZ25hdHVyZSA9IGZ1bmN0aW9uIG1ha2VTaWduYXR1cmUoc2lnKSB7XG4gIGlmIChzaWcgaW5zdGFuY2VvZiBTaWduYXR1cmUpXG4gICAgcmV0dXJuIHNpZztcbiAgcmV0dXJuIG5ldyBTaWduYXR1cmUodGhpcywgc2lnKTtcbn07XG5cbi8qKlxuKiAqIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9kcmFmdC1qb3NlZnNzb24tZWRkc2EtZWQyNTUxOS0wMyNzZWN0aW9uLTUuMlxuKlxuKiBFRERTQSBkZWZpbmVzIG1ldGhvZHMgZm9yIGVuY29kaW5nIGFuZCBkZWNvZGluZyBwb2ludHMgYW5kIGludGVnZXJzLiBUaGVzZSBhcmVcbiogaGVscGVyIGNvbnZlbmllbmNlIG1ldGhvZHMsIHRoYXQgcGFzcyBhbG9uZyB0byB1dGlsaXR5IGZ1bmN0aW9ucyBpbXBsaWVkXG4qIHBhcmFtZXRlcnMuXG4qXG4qL1xuRUREU0EucHJvdG90eXBlLmVuY29kZVBvaW50ID0gZnVuY3Rpb24gZW5jb2RlUG9pbnQocG9pbnQpIHtcbiAgdmFyIGVuYyA9IHBvaW50LmdldFkoKS50b0FycmF5KCdsZScsIHRoaXMuZW5jb2RpbmdMZW5ndGgpO1xuICBlbmNbdGhpcy5lbmNvZGluZ0xlbmd0aCAtIDFdIHw9IHBvaW50LmdldFgoKS5pc09kZCgpID8gMHg4MCA6IDA7XG4gIHJldHVybiBlbmM7XG59O1xuXG5FRERTQS5wcm90b3R5cGUuZGVjb2RlUG9pbnQgPSBmdW5jdGlvbiBkZWNvZGVQb2ludChieXRlcykge1xuICBieXRlcyA9IHV0aWxzLnBhcnNlQnl0ZXMoYnl0ZXMpO1xuXG4gIHZhciBsYXN0SXggPSBieXRlcy5sZW5ndGggLSAxO1xuICB2YXIgbm9ybWVkID0gYnl0ZXMuc2xpY2UoMCwgbGFzdEl4KS5jb25jYXQoYnl0ZXNbbGFzdEl4XSAmIH4weDgwKTtcbiAgdmFyIHhJc09kZCA9IChieXRlc1tsYXN0SXhdICYgMHg4MCkgIT09IDA7XG5cbiAgdmFyIHkgPSB1dGlscy5pbnRGcm9tTEUobm9ybWVkKTtcbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnRGcm9tWSh5LCB4SXNPZGQpO1xufTtcblxuRUREU0EucHJvdG90eXBlLmVuY29kZUludCA9IGZ1bmN0aW9uIGVuY29kZUludChudW0pIHtcbiAgcmV0dXJuIG51bS50b0FycmF5KCdsZScsIHRoaXMuZW5jb2RpbmdMZW5ndGgpO1xufTtcblxuRUREU0EucHJvdG90eXBlLmRlY29kZUludCA9IGZ1bmN0aW9uIGRlY29kZUludChieXRlcykge1xuICByZXR1cm4gdXRpbHMuaW50RnJvbUxFKGJ5dGVzKTtcbn07XG5cbkVERFNBLnByb3RvdHlwZS5pc1BvaW50ID0gZnVuY3Rpb24gaXNQb2ludCh2YWwpIHtcbiAgcmV0dXJuIHZhbCBpbnN0YW5jZW9mIHRoaXMucG9pbnRDbGFzcztcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBlbGxpcHRpYyA9IHJlcXVpcmUoJy4uLy4uL2VsbGlwdGljJyk7XG52YXIgdXRpbHMgPSBlbGxpcHRpYy51dGlscztcbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG52YXIgcGFyc2VCeXRlcyA9IHV0aWxzLnBhcnNlQnl0ZXM7XG52YXIgY2FjaGVkUHJvcGVydHkgPSB1dGlscy5jYWNoZWRQcm9wZXJ0eTtcblxuLyoqXG4qIEBwYXJhbSB7RUREU0F9IGVkZHNhIC0gaW5zdGFuY2VcbiogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyAtIHB1YmxpYy9wcml2YXRlIGtleSBwYXJhbWV0ZXJzXG4qXG4qIEBwYXJhbSB7QXJyYXk8Qnl0ZT59IFtwYXJhbXMuc2VjcmV0XSAtIHNlY3JldCBzZWVkIGJ5dGVzXG4qIEBwYXJhbSB7UG9pbnR9IFtwYXJhbXMucHViXSAtIHB1YmxpYyBrZXkgcG9pbnQgKGFrYSBgQWAgaW4gZWRkc2EgdGVybXMpXG4qIEBwYXJhbSB7QXJyYXk8Qnl0ZT59IFtwYXJhbXMucHViXSAtIHB1YmxpYyBrZXkgcG9pbnQgZW5jb2RlZCBhcyBieXRlc1xuKlxuKi9cbmZ1bmN0aW9uIEtleVBhaXIoZWRkc2EsIHBhcmFtcykge1xuICB0aGlzLmVkZHNhID0gZWRkc2E7XG4gIHRoaXMuX3NlY3JldCA9IHBhcnNlQnl0ZXMocGFyYW1zLnNlY3JldCk7XG4gIGlmIChlZGRzYS5pc1BvaW50KHBhcmFtcy5wdWIpKVxuICAgIHRoaXMuX3B1YiA9IHBhcmFtcy5wdWI7XG4gIGVsc2VcbiAgICB0aGlzLl9wdWJCeXRlcyA9IHBhcnNlQnl0ZXMocGFyYW1zLnB1Yik7XG59XG5cbktleVBhaXIuZnJvbVB1YmxpYyA9IGZ1bmN0aW9uIGZyb21QdWJsaWMoZWRkc2EsIHB1Yikge1xuICBpZiAocHViIGluc3RhbmNlb2YgS2V5UGFpcilcbiAgICByZXR1cm4gcHViO1xuICByZXR1cm4gbmV3IEtleVBhaXIoZWRkc2EsIHsgcHViOiBwdWIgfSk7XG59O1xuXG5LZXlQYWlyLmZyb21TZWNyZXQgPSBmdW5jdGlvbiBmcm9tU2VjcmV0KGVkZHNhLCBzZWNyZXQpIHtcbiAgaWYgKHNlY3JldCBpbnN0YW5jZW9mIEtleVBhaXIpXG4gICAgcmV0dXJuIHNlY3JldDtcbiAgcmV0dXJuIG5ldyBLZXlQYWlyKGVkZHNhLCB7IHNlY3JldDogc2VjcmV0IH0pO1xufTtcblxuS2V5UGFpci5wcm90b3R5cGUuc2VjcmV0ID0gZnVuY3Rpb24gc2VjcmV0KCkge1xuICByZXR1cm4gdGhpcy5fc2VjcmV0O1xufTtcblxuY2FjaGVkUHJvcGVydHkoS2V5UGFpciwgZnVuY3Rpb24gcHViQnl0ZXMoKSB7XG4gIHJldHVybiB0aGlzLmVkZHNhLmVuY29kZVBvaW50KHRoaXMucHViKCkpO1xufSk7XG5cbmNhY2hlZFByb3BlcnR5KEtleVBhaXIsIGZ1bmN0aW9uIHB1YigpIHtcbiAgaWYgKHRoaXMuX3B1YkJ5dGVzKVxuICAgIHJldHVybiB0aGlzLmVkZHNhLmRlY29kZVBvaW50KHRoaXMuX3B1YkJ5dGVzKTtcbiAgcmV0dXJuIHRoaXMuZWRkc2EuZy5tdWwodGhpcy5wcml2KCkpO1xufSk7XG5cbmNhY2hlZFByb3BlcnR5KEtleVBhaXIsIGZ1bmN0aW9uIHByaXZCeXRlcygpIHtcbiAgdmFyIGVkZHNhID0gdGhpcy5lZGRzYTtcbiAgdmFyIGhhc2ggPSB0aGlzLmhhc2goKTtcbiAgdmFyIGxhc3RJeCA9IGVkZHNhLmVuY29kaW5nTGVuZ3RoIC0gMTtcblxuICB2YXIgYSA9IGhhc2guc2xpY2UoMCwgZWRkc2EuZW5jb2RpbmdMZW5ndGgpO1xuICBhWzBdICY9IDI0ODtcbiAgYVtsYXN0SXhdICY9IDEyNztcbiAgYVtsYXN0SXhdIHw9IDY0O1xuXG4gIHJldHVybiBhO1xufSk7XG5cbmNhY2hlZFByb3BlcnR5KEtleVBhaXIsIGZ1bmN0aW9uIHByaXYoKSB7XG4gIHJldHVybiB0aGlzLmVkZHNhLmRlY29kZUludCh0aGlzLnByaXZCeXRlcygpKTtcbn0pO1xuXG5jYWNoZWRQcm9wZXJ0eShLZXlQYWlyLCBmdW5jdGlvbiBoYXNoKCkge1xuICByZXR1cm4gdGhpcy5lZGRzYS5oYXNoKCkudXBkYXRlKHRoaXMuc2VjcmV0KCkpLmRpZ2VzdCgpO1xufSk7XG5cbmNhY2hlZFByb3BlcnR5KEtleVBhaXIsIGZ1bmN0aW9uIG1lc3NhZ2VQcmVmaXgoKSB7XG4gIHJldHVybiB0aGlzLmhhc2goKS5zbGljZSh0aGlzLmVkZHNhLmVuY29kaW5nTGVuZ3RoKTtcbn0pO1xuXG5LZXlQYWlyLnByb3RvdHlwZS5zaWduID0gZnVuY3Rpb24gc2lnbihtZXNzYWdlKSB7XG4gIGFzc2VydCh0aGlzLl9zZWNyZXQsICdLZXlQYWlyIGNhbiBvbmx5IHZlcmlmeScpO1xuICByZXR1cm4gdGhpcy5lZGRzYS5zaWduKG1lc3NhZ2UsIHRoaXMpO1xufTtcblxuS2V5UGFpci5wcm90b3R5cGUudmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UsIHNpZykge1xuICByZXR1cm4gdGhpcy5lZGRzYS52ZXJpZnkobWVzc2FnZSwgc2lnLCB0aGlzKTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLmdldFNlY3JldCA9IGZ1bmN0aW9uIGdldFNlY3JldChlbmMpIHtcbiAgYXNzZXJ0KHRoaXMuX3NlY3JldCwgJ0tleVBhaXIgaXMgcHVibGljIG9ubHknKTtcbiAgcmV0dXJuIHV0aWxzLmVuY29kZSh0aGlzLnNlY3JldCgpLCBlbmMpO1xufTtcblxuS2V5UGFpci5wcm90b3R5cGUuZ2V0UHVibGljID0gZnVuY3Rpb24gZ2V0UHVibGljKGVuYykge1xuICByZXR1cm4gdXRpbHMuZW5jb2RlKHRoaXMucHViQnl0ZXMoKSwgZW5jKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gS2V5UGFpcjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciBlbGxpcHRpYyA9IHJlcXVpcmUoJy4uLy4uL2VsbGlwdGljJyk7XG52YXIgdXRpbHMgPSBlbGxpcHRpYy51dGlscztcbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG52YXIgY2FjaGVkUHJvcGVydHkgPSB1dGlscy5jYWNoZWRQcm9wZXJ0eTtcbnZhciBwYXJzZUJ5dGVzID0gdXRpbHMucGFyc2VCeXRlcztcblxuLyoqXG4qIEBwYXJhbSB7RUREU0F9IGVkZHNhIC0gZWRkc2EgaW5zdGFuY2VcbiogQHBhcmFtIHtBcnJheTxCeXRlcz58T2JqZWN0fSBzaWcgLVxuKiBAcGFyYW0ge0FycmF5PEJ5dGVzPnxQb2ludH0gW3NpZy5SXSAtIFIgcG9pbnQgYXMgUG9pbnQgb3IgYnl0ZXNcbiogQHBhcmFtIHtBcnJheTxCeXRlcz58Ym59IFtzaWcuU10gLSBTIHNjYWxhciBhcyBibiBvciBieXRlc1xuKiBAcGFyYW0ge0FycmF5PEJ5dGVzPn0gW3NpZy5SZW5jb2RlZF0gLSBSIHBvaW50IGVuY29kZWRcbiogQHBhcmFtIHtBcnJheTxCeXRlcz59IFtzaWcuU2VuY29kZWRdIC0gUyBzY2FsYXIgZW5jb2RlZFxuKi9cbmZ1bmN0aW9uIFNpZ25hdHVyZShlZGRzYSwgc2lnKSB7XG4gIHRoaXMuZWRkc2EgPSBlZGRzYTtcblxuICBpZiAodHlwZW9mIHNpZyAhPT0gJ29iamVjdCcpXG4gICAgc2lnID0gcGFyc2VCeXRlcyhzaWcpO1xuXG4gIGlmIChBcnJheS5pc0FycmF5KHNpZykpIHtcbiAgICBzaWcgPSB7XG4gICAgICBSOiBzaWcuc2xpY2UoMCwgZWRkc2EuZW5jb2RpbmdMZW5ndGgpLFxuICAgICAgUzogc2lnLnNsaWNlKGVkZHNhLmVuY29kaW5nTGVuZ3RoKVxuICAgIH07XG4gIH1cblxuICBhc3NlcnQoc2lnLlIgJiYgc2lnLlMsICdTaWduYXR1cmUgd2l0aG91dCBSIG9yIFMnKTtcblxuICBpZiAoZWRkc2EuaXNQb2ludChzaWcuUikpXG4gICAgdGhpcy5fUiA9IHNpZy5SO1xuICBpZiAoc2lnLlMgaW5zdGFuY2VvZiBCTilcbiAgICB0aGlzLl9TID0gc2lnLlM7XG5cbiAgdGhpcy5fUmVuY29kZWQgPSBBcnJheS5pc0FycmF5KHNpZy5SKSA/IHNpZy5SIDogc2lnLlJlbmNvZGVkO1xuICB0aGlzLl9TZW5jb2RlZCA9IEFycmF5LmlzQXJyYXkoc2lnLlMpID8gc2lnLlMgOiBzaWcuU2VuY29kZWQ7XG59XG5cbmNhY2hlZFByb3BlcnR5KFNpZ25hdHVyZSwgZnVuY3Rpb24gUygpIHtcbiAgcmV0dXJuIHRoaXMuZWRkc2EuZGVjb2RlSW50KHRoaXMuU2VuY29kZWQoKSk7XG59KTtcblxuY2FjaGVkUHJvcGVydHkoU2lnbmF0dXJlLCBmdW5jdGlvbiBSKCkge1xuICByZXR1cm4gdGhpcy5lZGRzYS5kZWNvZGVQb2ludCh0aGlzLlJlbmNvZGVkKCkpO1xufSk7XG5cbmNhY2hlZFByb3BlcnR5KFNpZ25hdHVyZSwgZnVuY3Rpb24gUmVuY29kZWQoKSB7XG4gIHJldHVybiB0aGlzLmVkZHNhLmVuY29kZVBvaW50KHRoaXMuUigpKTtcbn0pO1xuXG5jYWNoZWRQcm9wZXJ0eShTaWduYXR1cmUsIGZ1bmN0aW9uIFNlbmNvZGVkKCkge1xuICByZXR1cm4gdGhpcy5lZGRzYS5lbmNvZGVJbnQodGhpcy5TKCkpO1xufSk7XG5cblNpZ25hdHVyZS5wcm90b3R5cGUudG9CeXRlcyA9IGZ1bmN0aW9uIHRvQnl0ZXMoKSB7XG4gIHJldHVybiB0aGlzLlJlbmNvZGVkKCkuY29uY2F0KHRoaXMuU2VuY29kZWQoKSk7XG59O1xuXG5TaWduYXR1cmUucHJvdG90eXBlLnRvSGV4ID0gZnVuY3Rpb24gdG9IZXgoKSB7XG4gIHJldHVybiB1dGlscy5lbmNvZGUodGhpcy50b0J5dGVzKCksICdoZXgnKS50b1VwcGVyQ2FzZSgpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBTaWduYXR1cmU7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNoID0gcmVxdWlyZSgnaGFzaC5qcycpO1xudmFyIGVsbGlwdGljID0gcmVxdWlyZSgnLi4vZWxsaXB0aWMnKTtcbnZhciB1dGlscyA9IGVsbGlwdGljLnV0aWxzO1xudmFyIGFzc2VydCA9IHV0aWxzLmFzc2VydDtcblxuZnVuY3Rpb24gSG1hY0RSQkcob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgSG1hY0RSQkcpKVxuICAgIHJldHVybiBuZXcgSG1hY0RSQkcob3B0aW9ucyk7XG4gIHRoaXMuaGFzaCA9IG9wdGlvbnMuaGFzaDtcbiAgdGhpcy5wcmVkUmVzaXN0ID0gISFvcHRpb25zLnByZWRSZXNpc3Q7XG5cbiAgdGhpcy5vdXRMZW4gPSB0aGlzLmhhc2gub3V0U2l6ZTtcbiAgdGhpcy5taW5FbnRyb3B5ID0gb3B0aW9ucy5taW5FbnRyb3B5IHx8IHRoaXMuaGFzaC5obWFjU3RyZW5ndGg7XG5cbiAgdGhpcy5yZXNlZWQgPSBudWxsO1xuICB0aGlzLnJlc2VlZEludGVydmFsID0gbnVsbDtcbiAgdGhpcy5LID0gbnVsbDtcbiAgdGhpcy5WID0gbnVsbDtcblxuICB2YXIgZW50cm9weSA9IHV0aWxzLnRvQXJyYXkob3B0aW9ucy5lbnRyb3B5LCBvcHRpb25zLmVudHJvcHlFbmMpO1xuICB2YXIgbm9uY2UgPSB1dGlscy50b0FycmF5KG9wdGlvbnMubm9uY2UsIG9wdGlvbnMubm9uY2VFbmMpO1xuICB2YXIgcGVycyA9IHV0aWxzLnRvQXJyYXkob3B0aW9ucy5wZXJzLCBvcHRpb25zLnBlcnNFbmMpO1xuICBhc3NlcnQoZW50cm9weS5sZW5ndGggPj0gKHRoaXMubWluRW50cm9weSAvIDgpLFxuICAgICAgICAgJ05vdCBlbm91Z2ggZW50cm9weS4gTWluaW11bSBpczogJyArIHRoaXMubWluRW50cm9weSArICcgYml0cycpO1xuICB0aGlzLl9pbml0KGVudHJvcHksIG5vbmNlLCBwZXJzKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gSG1hY0RSQkc7XG5cbkhtYWNEUkJHLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uIGluaXQoZW50cm9weSwgbm9uY2UsIHBlcnMpIHtcbiAgdmFyIHNlZWQgPSBlbnRyb3B5LmNvbmNhdChub25jZSkuY29uY2F0KHBlcnMpO1xuXG4gIHRoaXMuSyA9IG5ldyBBcnJheSh0aGlzLm91dExlbiAvIDgpO1xuICB0aGlzLlYgPSBuZXcgQXJyYXkodGhpcy5vdXRMZW4gLyA4KTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLlYubGVuZ3RoOyBpKyspIHtcbiAgICB0aGlzLktbaV0gPSAweDAwO1xuICAgIHRoaXMuVltpXSA9IDB4MDE7XG4gIH1cblxuICB0aGlzLl91cGRhdGUoc2VlZCk7XG4gIHRoaXMucmVzZWVkID0gMTtcbiAgdGhpcy5yZXNlZWRJbnRlcnZhbCA9IDB4MTAwMDAwMDAwMDAwMDsgIC8vIDJeNDhcbn07XG5cbkhtYWNEUkJHLnByb3RvdHlwZS5faG1hYyA9IGZ1bmN0aW9uIGhtYWMoKSB7XG4gIHJldHVybiBuZXcgaGFzaC5obWFjKHRoaXMuaGFzaCwgdGhpcy5LKTtcbn07XG5cbkhtYWNEUkJHLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKHNlZWQpIHtcbiAgdmFyIGttYWMgPSB0aGlzLl9obWFjKClcbiAgICAgICAgICAgICAgICAgLnVwZGF0ZSh0aGlzLlYpXG4gICAgICAgICAgICAgICAgIC51cGRhdGUoWyAweDAwIF0pO1xuICBpZiAoc2VlZClcbiAgICBrbWFjID0ga21hYy51cGRhdGUoc2VlZCk7XG4gIHRoaXMuSyA9IGttYWMuZGlnZXN0KCk7XG4gIHRoaXMuViA9IHRoaXMuX2htYWMoKS51cGRhdGUodGhpcy5WKS5kaWdlc3QoKTtcbiAgaWYgKCFzZWVkKVxuICAgIHJldHVybjtcblxuICB0aGlzLksgPSB0aGlzLl9obWFjKClcbiAgICAgICAgICAgICAgIC51cGRhdGUodGhpcy5WKVxuICAgICAgICAgICAgICAgLnVwZGF0ZShbIDB4MDEgXSlcbiAgICAgICAgICAgICAgIC51cGRhdGUoc2VlZClcbiAgICAgICAgICAgICAgIC5kaWdlc3QoKTtcbiAgdGhpcy5WID0gdGhpcy5faG1hYygpLnVwZGF0ZSh0aGlzLlYpLmRpZ2VzdCgpO1xufTtcblxuSG1hY0RSQkcucHJvdG90eXBlLnJlc2VlZCA9IGZ1bmN0aW9uIHJlc2VlZChlbnRyb3B5LCBlbnRyb3B5RW5jLCBhZGQsIGFkZEVuYykge1xuICAvLyBPcHRpb25hbCBlbnRyb3B5IGVuY1xuICBpZiAodHlwZW9mIGVudHJvcHlFbmMgIT09ICdzdHJpbmcnKSB7XG4gICAgYWRkRW5jID0gYWRkO1xuICAgIGFkZCA9IGVudHJvcHlFbmM7XG4gICAgZW50cm9weUVuYyA9IG51bGw7XG4gIH1cblxuICBlbnRyb3B5ID0gdXRpbHMudG9CdWZmZXIoZW50cm9weSwgZW50cm9weUVuYyk7XG4gIGFkZCA9IHV0aWxzLnRvQnVmZmVyKGFkZCwgYWRkRW5jKTtcblxuICBhc3NlcnQoZW50cm9weS5sZW5ndGggPj0gKHRoaXMubWluRW50cm9weSAvIDgpLFxuICAgICAgICAgJ05vdCBlbm91Z2ggZW50cm9weS4gTWluaW11bSBpczogJyArIHRoaXMubWluRW50cm9weSArICcgYml0cycpO1xuXG4gIHRoaXMuX3VwZGF0ZShlbnRyb3B5LmNvbmNhdChhZGQgfHwgW10pKTtcbiAgdGhpcy5yZXNlZWQgPSAxO1xufTtcblxuSG1hY0RSQkcucHJvdG90eXBlLmdlbmVyYXRlID0gZnVuY3Rpb24gZ2VuZXJhdGUobGVuLCBlbmMsIGFkZCwgYWRkRW5jKSB7XG4gIGlmICh0aGlzLnJlc2VlZCA+IHRoaXMucmVzZWVkSW50ZXJ2YWwpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdSZXNlZWQgaXMgcmVxdWlyZWQnKTtcblxuICAvLyBPcHRpb25hbCBlbmNvZGluZ1xuICBpZiAodHlwZW9mIGVuYyAhPT0gJ3N0cmluZycpIHtcbiAgICBhZGRFbmMgPSBhZGQ7XG4gICAgYWRkID0gZW5jO1xuICAgIGVuYyA9IG51bGw7XG4gIH1cblxuICAvLyBPcHRpb25hbCBhZGRpdGlvbmFsIGRhdGFcbiAgaWYgKGFkZCkge1xuICAgIGFkZCA9IHV0aWxzLnRvQXJyYXkoYWRkLCBhZGRFbmMpO1xuICAgIHRoaXMuX3VwZGF0ZShhZGQpO1xuICB9XG5cbiAgdmFyIHRlbXAgPSBbXTtcbiAgd2hpbGUgKHRlbXAubGVuZ3RoIDwgbGVuKSB7XG4gICAgdGhpcy5WID0gdGhpcy5faG1hYygpLnVwZGF0ZSh0aGlzLlYpLmRpZ2VzdCgpO1xuICAgIHRlbXAgPSB0ZW1wLmNvbmNhdCh0aGlzLlYpO1xuICB9XG5cbiAgdmFyIHJlcyA9IHRlbXAuc2xpY2UoMCwgbGVuKTtcbiAgdGhpcy5fdXBkYXRlKGFkZCk7XG4gIHRoaXMucmVzZWVkKys7XG4gIHJldHVybiB1dGlscy5lbmNvZGUocmVzLCBlbmMpO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBkb3VibGVzOiB7XG4gICAgc3RlcDogNCxcbiAgICBwb2ludHM6IFtcbiAgICAgIFtcbiAgICAgICAgJ2U2MGZjZTkzYjU5ZTllYzUzMDExYWFiYzIxYzIzZTk3YjJhMzEzNjliODdhNWFlOWM0NGVlODllMmE2ZGVjMGEnLFxuICAgICAgICAnZjdlMzUwNzM5OWU1OTU5MjlkYjk5ZjM0ZjU3OTM3MTAxMjk2ODkxZTQ0ZDIzZjBiZTFmMzJjY2U2OTYxNjgyMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4MjgyMjYzMjEyYzYwOWQ5ZWEyYTZlM2UxNzJkZTIzOGQ4YzM5Y2FiZDVhYzFjYTEwNjQ2ZTIzZmQ1ZjUxNTA4JyxcbiAgICAgICAgJzExZjhhODA5ODU1N2RmZTQ1ZTgyNTZlODMwYjYwYWNlNjJkNjEzYWMyZjdiMTdiZWQzMWI2ZWFmZjZlMjZjYWYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMTc1ZTE1OWY3MjhiODY1YTcyZjk5Y2M2YzZmYzg0NmRlMGI5MzgzM2ZkMjIyMmVkNzNmY2U1YjU1MWU1YjczOScsXG4gICAgICAgICdkMzUwNmUwZDllM2M3OWViYTRlZjk3YTUxZmY3MWY1ZWFjYjU5NTVhZGQyNDM0NWM2ZWZhNmZmZWU5ZmVkNjk1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzM2M2Q5MGQ0NDdiMDBjOWM5OWNlYWMwNWI2MjYyZWUwNTM0NDFjN2U1NTU1MmZmZTUyNmJhZDhmODNmZjQ2NDAnLFxuICAgICAgICAnNGUyNzNhZGZjNzMyMjIxOTUzYjQ0NTM5N2YzMzYzMTQ1YjlhODkwMDgxOTllY2I2MjAwM2M3ZjNiZWU5ZGU5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzhiNGI1ZjE2NWRmM2MyYmU4YzYyNDRiNWI3NDU2Mzg4NDNlNGE3ODFhMTViY2QxYjY5Zjc5YTU1ZGZmZGY4MGMnLFxuICAgICAgICAnNGFhZDBhNmY2OGQzMDhiNGIzZmJkNzgxM2FiMGRhMDRmOWUzMzY1NDYxNjJlZTU2YjNlZmYwYzY1ZmQ0ZmQzNidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3MjNjYmFhNmU1ZGI5OTZkNmJmNzcxYzAwYmQ1NDhjN2I3MDBkYmZmYTZjMGU3N2JjYjYxMTU5MjUyMzJmY2RhJyxcbiAgICAgICAgJzk2ZTg2N2I1NTk1Y2M0OThhOTIxMTM3NDg4ODI0ZDZlMjY2MGEwNjUzNzc5NDk0ODAxZGMwNjlkOWViMzlmNWYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZWViZmE0ZDQ5M2JlYmY5OGJhNWZlZWM4MTJjMmQzYjUwOTQ3OTYxMjM3YTkxOTgzOWE1MzNlY2EwZTdkZDdmYScsXG4gICAgICAgICc1ZDlhOGNhMzk3MGVmMGYyNjllZTdlZGFmMTc4MDg5ZDlhZTRjZGMzYTcxMWY3MTJkZGZkNGZkYWUxZGU4OTk5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzEwMGY0NGRhNjk2ZTcxNjcyNzkxZDBhMDliN2JkZTQ1OWYxMjE1YTI5YjNjMDNiZmVmZDc4MzViMzlhNDhkYjAnLFxuICAgICAgICAnY2RkOWUxMzE5MmEwMGI3NzJlYzhmMzMwMGMwOTA2NjZiN2ZmNGExOGZmNTE5NWFjMGZiZDVjZDYyYmM2NWEwOSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlMTAzMWJlMjYyYzdlZDFiMWRjOTIyN2E0YTA0YzAxN2E3N2Y4ZDQ0NjRmM2IzODUyYzhhY2RlNmU1MzRmZDJkJyxcbiAgICAgICAgJzlkNzA2MTkyODk0MDQwNWU2YmI2YTQxNzY1OTc1MzVhZjI5MmRkNDE5ZTFjZWQ3OWE0NGYxOGYyOTQ1NmEwMGQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZmVlYTZjYWU0NmQ1NWI1MzBhYzI4MzlmMTQzYmQ3ZWM1Y2Y4YjI2NmE0MWQ2YWY1MmQ1ZTY4OGQ5MDk0Njk2ZCcsXG4gICAgICAgICdlNTdjNmI2Yzk3ZGNlMWJhYjA2ZTRlMTJiZjNlY2Q1Yzk4MWM4OTU3Y2M0MTQ0MmQzMTU1ZGViZjE4MDkwMDg4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2RhNjdhOTFkOTEwNDljZGNiMzY3YmU0YmU2ZmZjYTNjZmVlZDY1N2Q4MDg1ODNkZTMzZmE5NzhiYzFlYzZjYjEnLFxuICAgICAgICAnOWJhY2FhMzU0ODE2NDJiYzQxZjQ2M2Y3ZWM5NzgwZTVkZWM3YWRjNTA4Zjc0MGExN2U5ZWE4ZTI3YTY4YmUxZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc1MzkwNGZhYTBiMzM0Y2RkYTZlMDAwOTM1ZWYyMjE1MWVjMDhkMGY3YmIxMTA2OWY1NzU0NWNjYzFhMzdiN2MwJyxcbiAgICAgICAgJzViYzA4N2QwYmM4MDEwNmQ4OGM5ZWNjYWMyMGQzYzFjMTM5OTk5ODFlMTQ0MzQ2OTlkY2IwOTZiMDIyNzcxYzgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOGU3YmNkMGJkMzU5ODNhNzcxOWNjYTc3NjRjYTkwNjc3OWI1M2EwNDNhOWI4YmNhZWZmOTU5ZjQzYWQ4NjA0NycsXG4gICAgICAgICcxMGI3NzcwYjJhM2RhNGIzOTQwMzEwNDIwY2E5NTE0NTc5ZTg4ZTJlNDdmZDY4YjNlYTEwMDQ3ZTg0NjAzNzJhJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzM4NWVlZDM0YzFjZGZmMjFlNmQwODE4Njg5YjgxYmRlNzFhN2Y0ZjE4Mzk3ZTY2OTBhODQxZTE1OTljNDM4NjInLFxuICAgICAgICAnMjgzYmViYzNlOGVhMjNmNTY3MDFkZTE5ZTllYmY0NTc2YjMwNGVlYzIwODZkYzhjYzA0NThmZTU1NDJlNTQ1MydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc2ZjlkOWI4MDNlY2YxOTE2MzdjNzNhNDQxM2RmYTE4MGZkZGY4NGE1OTQ3ZmJjOWM2MDZlZDg2YzNmYWMzYTcnLFxuICAgICAgICAnN2M4MGM2OGU2MDMwNTliYTY5YjhlMmEzMGU0NWM0ZDQ3ZWE0ZGQyZjVjMjgxMDAyZDg2ODkwNjAzYTg0MjE2MCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczMzIyZDQwMTI0M2M0ZTI1ODJhMjE0N2MxMDRkNmVjYmY3NzRkMTYzZGIwZjVlNTMxM2I3ZTBlNzQyZDBlNmJkJyxcbiAgICAgICAgJzU2ZTcwNzk3ZTk2NjRlZjViZmIwMTliYzRkZGFmOWI3MjgwNWY2M2VhMjg3M2FmNjI0ZjNhMmU5NmMyOGIyYTAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnODU2NzJjN2QyZGUwYjdkYTJiZDE3NzBkODk2NjU4Njg3NDFiM2Y5YWY3NjQzMzk3NzIxZDc0ZDI4MTM0YWI4MycsXG4gICAgICAgICc3YzQ4MWI5YjViNDNiMmViNjM3NDA0OWJmYTYyYzJlNWU3N2YxN2ZjYzUyOThmNDRjOGUzMDk0Zjc5MDMxM2E2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzk0OGJmODA5YjE5ODhhNDZiMDZjOWYxOTE5NDEzYjEwZjkyMjZjNjBmNjY4ODMyZmZkOTU5YWY2MGM4MmEwYScsXG4gICAgICAgICc1M2E1NjI4NTZkY2I2NjQ2ZGM2Yjc0YzVkMWMzNDE4YzZkNGRmZjA4Yzk3Y2QyYmVkNGNiN2Y4OGQ4YzhlNTg5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzYyNjBjZTdmNDYxODAxYzM0ZjA2N2NlMGYwMjg3M2E4ZjFiMGU0NGRmYzY5NzUyYWNjZWNkODE5ZjM4ZmQ4ZTgnLFxuICAgICAgICAnYmMyZGE4MmI2ZmE1YjU3MWE3ZjA5MDQ5Nzc2YTFlZjdlY2QyOTIyMzgwNTFjMTk4YzFhODRlOTViMmI0YWUxNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlNTAzN2RlMGFmYzFkOGQ0M2Q4MzQ4NDE0YmJmNDEwMzA0M2VjOGY1NzViZmRjNDMyOTUzY2M4ZDIwMzdmYTJkJyxcbiAgICAgICAgJzQ1NzE1MzRiYWE5NGQzYjVmOWY5OGQwOWZiOTkwYmRkYmQ1ZjViMDNlYzQ4MWYxMGUwZTVkYzg0MWQ3NTViZGEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTA2MzcyYjBmNGEyMDdhZGY1ZWE5MDVlOGYxNzcxYjRlN2U4ZGJkMWM2YTZjNWI3MjU4NjZhMGFlNGZjZTcyNScsXG4gICAgICAgICc3YTkwODk3NGJjZTE4Y2ZlMTJhMjdiYjJhZDVhNDg4Y2Q3NDg0YTc3ODcxMDQ4NzBiMjcwMzRmOTRlZWUzMWRkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzIxM2M3YTcxNWNkNWQ0NTM1OGQwYmJmOWRjMGNlMDIyMDRiMTBiZGRlMmEzZjU4NTQwYWQ2OTA4ZDA1NTk3NTQnLFxuICAgICAgICAnNGI2ZGFkMGI1YWU0NjI1MDcwMTNhZDA2MjQ1YmExOTBiYjQ4NTBmNWYzNmE3ZWVkZGZmMmMyNzUzNGI0NThmMidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc0ZTdjMjcyYTdhZjRiMzRlOGRiYjkzNTJhNTQxOWE4N2UyODM4YzcwYWRjNjJjZGRmMGNjM2EzYjA4ZmJkNTNjJyxcbiAgICAgICAgJzE3NzQ5Yzc2NmM5ZDBiMThlMTZmZDA5ZjZkZWY2ODFiNTMwYjk2MTRiZmY3ZGQzM2UwYjM5NDE4MTdkY2FhZTYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZmVhNzRlM2RiZTc3OGIxYjEwZjIzOGFkNjE2ODZhYTVjNzZlM2RiMmJlNDMwNTc2MzI0MjdlMjg0MGZiMjdiNicsXG4gICAgICAgICc2ZTA1NjhkYjliMGIxMzI5N2NmNjc0ZGVjY2I2YWY5MzEyNmI1OTZiOTczZjdiNzc3MDFkM2RiN2YyM2NiOTZmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc2ZTY0MTEzZjY3N2NmMGUxMGEyNTcwZDU5OTk2OGQzMTU0NGUxNzliNzYwNDMyOTUyYzAyYTQ0MTdiZGRlMzknLFxuICAgICAgICAnYzkwZGRmOGRlZTRlOTVjZjU3NzA2NmQ3MDY4MWYwZDM1ZTJhMzNkMmI1NmQyMDMyYjRiMTc1MmQxOTAxYWMwMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdjNzM4YzU2YjAzYjJhYmUxZTgyODFiYWE3NDNmOGY5YThmN2NjNjQzZGYyNmNiZWUzYWIxNTAyNDJiY2JiODkxJyxcbiAgICAgICAgJzg5M2ZiNTc4OTUxYWQyNTM3ZjcxOGYyZWFjYmZiYmJiODIzMTRlZWY3ODgwY2ZlOTE3ZTczNWQ5Njk5YTg0YzMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDg5NTYyNjU0OGI2NWI4MWUyNjRjNzYzN2M5NzI4NzdkMWQ3MmU1ZjNhOTI1MDE0MzcyZTlmNjU4OGY2YzE0YicsXG4gICAgICAgICdmZWJmYWEzOGYyYmM3ZWFlNzI4ZWM2MDgxOGMzNDBlYjAzNDI4ZDYzMmJiMDY3ZTE3OTM2M2VkNzVkN2Q5OTFmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2I4ZGE5NDAzMmE5NTc1MThlYjBmNjQzMzU3MWU4NzYxY2VmZmM3MzY5M2U4NGVkZDQ5MTUwYTU2NGY2NzZlMDMnLFxuICAgICAgICAnMjgwNGRmYTQ0ODA1YTFlNGQ3Yzk5Y2M5NzYyODA4YjA5MmNjNTg0ZDk1ZmYzYjUxMTQ4OGU0ZTc0ZWZkZjZlNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlODBmZWExNDQ0MWZiMzNhN2Q4YWRhYjk0NzVkN2ZhYjIwMTllZmZiNTE1NmE3OTJmMWExMTc3OGUzYzBkZjVkJyxcbiAgICAgICAgJ2VlZDFkZTdmNjM4ZTAwNzcxZTg5NzY4Y2EzY2E5NDQ3MmQxNTVlODBhZjMyMmVhOWZjYjQyOTFiNmFjOWVjNzgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYTMwMTY5N2JkZmNkNzA0MzEzYmE0OGU1MWQ1Njc1NDNmMmExODIwMzFlZmQ2OTE1ZGRjMDdiYmNjNGUxNjA3MCcsXG4gICAgICAgICc3MzcwZjkxY2ZiNjdlNGY1MDgxODA5ZmEyNWQ0MGY5YjE3MzVkYmY3YzBhMTFhMTMwYzBkMWEwNDFlMTc3ZWExJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzkwYWQ4NWIzODlkNmI5MzY0NjNmOWQwNTEyNjc4ZGUyMDhjYzMzMGIxMTMwN2ZmZmFiN2FjNjNlM2ZiMDRlZDQnLFxuICAgICAgICAnZTUwN2EzNjIwYTM4MjYxYWZmZGNiZDk0MjcyMjJiODM5YWVmYWJlMTU4Mjg5NGQ5OTFkNGQ0OGNiNmVmMTUwJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzhmNjhiOWQyZjYzYjVmMzM5MjM5YzFhZDk4MWYxNjJlZTg4YzU2Nzg3MjNlYTMzNTFiN2I0NDRjOWVjNGMwZGEnLFxuICAgICAgICAnNjYyYTlmMmRiYTA2Mzk4NmRlMWQ5MGMyYjZiZTIxNWRiYmVhMmNmZTk1NTEwYmZkZjIzY2JmNzk1MDFmZmY4MidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlNGYzZmIwMTc2YWY4NWQ2NWZmOTlmZjkxOThjMzYwOTFmNDhlODY1MDM2ODFlM2U2Njg2ZmQ1MDUzMjMxZTExJyxcbiAgICAgICAgJzFlNjM2MzNhZDBlZjRmMWMxNjYxYTZkMGVhMDJiNzI4NmNjN2U3NGVjOTUxZDFjOTgyMmMzODU3NmZlYjczYmMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOGMwMGZhOWIxOGViZjMzMWViOTYxNTM3YTQ1YTQyNjZjNzAzNGYyZjBkNGUxZDA3MTZmYjZlYWUyMGVhZTI5ZScsXG4gICAgICAgICdlZmE0NzI2N2ZlYTUyMWExYTlkYzM0M2EzNzM2Yzk3NGMyZmFkYWZhODFlMzZjNTRlN2QyYTRjNjY3MDI0MTRiJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2U3YTI2Y2U2OWRkNDgyOWYzZTEwY2VjMGE5ZTk4ZWQzMTQzZDA4NGYzMDhiOTJjMDk5N2ZkZGZjNjBjYjNlNDEnLFxuICAgICAgICAnMmE3NThlMzAwZmE3OTg0YjQ3MWIwMDZhMWFhZmJiMThkMGE2YjJjMDQyMGU4M2UyMGU4YTk0MjFjZjJjZmQ1MSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdiNjQ1OWUwZWUzNjYyZWM4ZDIzNTQwYzIyM2JjYmRjNTcxY2JjYjk2N2Q3OTQyNGYzY2YyOWViM2RlNmI4MGVmJyxcbiAgICAgICAgJzY3Yzg3NmQwNmYzZTA2ZGUxZGFkZjE2ZTU2NjFkYjNjNGIzYWU2ZDQ4ZTM1YjJmZjMwYmYwYjYxYTcxYmE0NSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkNjhhODBjODI4MGJiODQwNzkzMjM0YWExMThmMDYyMzFkNmYxZmM2N2U3M2M1YTVkZWRhMGY1YjQ5Njk0M2U4JyxcbiAgICAgICAgJ2RiOGJhOWZmZjRiNTg2ZDAwYzRiMWY5MTc3YjBlMjhiNWIwZTdiOGY3ODQ1Mjk1YTI5NGM4NDI2NmIxMzMxMjAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzI0YWVkN2RmNjVjODA0MjUyZGMwMjcwOTA3YTMwYjA5NjEyYWViOTczNDQ5Y2VhNDA5NTk4MGZjMjhkM2Q1ZCcsXG4gICAgICAgICc2NDhhMzY1Nzc0YjYxZjJmZjEzMGMwYzM1YWVjMWY0ZjE5MjEzYjBjN2UzMzI4NDM5NjcyMjRhZjk2YWI3Yzg0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzRkZjljMTQ5MTljZGU2MWY2ZDUxZGZkYmU1ZmVlNWRjZWVjNDE0M2JhOGQxY2E4ODhlOGJkMzczZmQwNTRjOTYnLFxuICAgICAgICAnMzVlYzUxMDkyZDg3MjgwNTA5NzRjMjNhMWQ4NWQ0YjVkNTA2Y2RjMjg4NDkwMTkyZWJhYzA2Y2FkMTBkNWQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOWMzOTE5YTg0YTQ3NDg3MGZhZWQ4YTljMWNjNjYwMjE1MjM0ODkwNTRkN2YwMzA4Y2JmYzk5YzhhYzFmOThjZCcsXG4gICAgICAgICdkZGI4NGYwZjRhNGRkZDU3NTg0ZjA0NGJmMjYwZTY0MTkwNTMyNmY3NmM2NGM4ZTZiZTdlNWUwM2Q0ZmM1OTlkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzYwNTcxNzBiMWRkMTJmZGY4ZGUwNWYyODFkOGUwNmJiOTFlMTQ5M2E4YjkxZDRjYzVhMjEzODIxMjBhOTU5ZTUnLFxuICAgICAgICAnOWExYWYwYjI2YTZhNDgwN2FkZDlhMmRhZjcxZGYyNjI0NjUxNTJiYzNlZTI0YzY1ZTg5OWJlOTMyMzg1YTJhOCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhNTc2ZGY4ZTIzYTA4NDExNDIxNDM5YTQ1MThkYTMxODgwY2VmMGZiYTdkNGRmMTJiMWE2OTczZWVjYjk0MjY2JyxcbiAgICAgICAgJzQwYTZiZjIwZTc2NjQwYjJjOTJiOTdhZmU1OGNkODJjNDMyZTEwYTdmNTE0ZDlmM2VlOGJlMTFhZTFiMjhlYzgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzc3OGE3OGMyOGRlYzNlMzBhMDVmZTk2MjlkZThjMzhiYjMwZDFmNWNmOWEzYTIwOGY3NjM4ODliZTU4YWQ3MScsXG4gICAgICAgICczNDYyNmQ5YWI1YTViMjJmZjcwOThlMTJmMmZmNTgwMDg3YjM4NDExZmYyNGFjNTYzYjUxM2ZjMWZkOWY0M2FjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzkyODk1NWVlNjM3YTg0NDYzNzI5ZmQzMGU3YWZkMmVkNWY5NjI3NGU1YWQ3ZTVjYjA5ZWRhOWMwNmQ5MDNhYycsXG4gICAgICAgICdjMjU2MjEwMDNkM2Y0MmE4MjdiNzhhMTMwOTNhOTVlZWFjM2QyNmVmYThhOGQ4M2ZjNTE4MGU5MzViY2QwOTFmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzg1ZDBmZWYzZWM2ZGIxMDkzOTkwNjRmM2EwZTNiMjg1NTY0NWI0YTkwN2FkMzU0NTI3YWFlNzUxNjNkODI3NTEnLFxuICAgICAgICAnMWYwMzY0ODQxM2EzOGMwYmUyOWQ0OTZlNTgyY2Y1NjYzZTg3NTFlOTY4NzczMzE1ODJjMjM3YTI0ZWIxZjk2MidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmZjJiMGRjZTk3ZWVjZTk3YzFjOWI2MDQxNzk4Yjg1ZGZkZmI2ZDg4ODJkYTIwMzA4ZjU0MDQ4MjQ1MjYwODdlJyxcbiAgICAgICAgJzQ5M2QxM2ZlZjUyNGJhMTg4YWY0YzRkYzU0ZDA3OTM2YzdiN2VkNmZiOTBlMmNlYjJjOTUxZTAxZjBjMjk5MDcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnODI3ZmJiZTRiMWU4ODBlYTllZDJiMmU2MzAxYjIxMmI1N2YxZWUxNDhjZDZkZDI4NzgwZTVlMmNmODU2ZTI0MScsXG4gICAgICAgICdjNjBmOWM5MjNjNzI3YjBiNzFiZWYyYzY3ZDFkMTI2ODdmZjdhNjMxODY5MDMxNjZkNjA1YjY4YmFlYzI5M2VjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2VhYTY0OWYyMWY1MWJkYmFlN2JlNGFlMzRjZTZlNTIxN2E1OGZkY2U3ZjQ3ZjlhYTdmM2I1OGZhMjEyMGUyYjMnLFxuICAgICAgICAnYmUzMjc5ZWQ1YmJiYjAzYWM2OWE4MGY4OTg3OWFhNWEwMWE2Yjk2NWYxM2Y3ZTU5ZDQ3YTUzMDViYTVhZDkzZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlNGE0MmQ0M2M1Y2YxNjlkOTM5MWRmNmRlY2Y0MmVlNTQxYjZkOGYwYzlhMTM3NDAxZTIzNjMyZGRhMzRkMjRmJyxcbiAgICAgICAgJzRkOWY5MmU3MTZkMWM3MzUyNmZjOTljY2ZiOGFkMzRjZTg4NmVlZGZhOGQ4ZTRmMTNhN2Y3MTMxZGViYTk0MTQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMWVjODBmZWYzNjBjYmRkOTU0MTYwZmFkYWIzNTJiNmI5MmI1MzU3NmE4OGZlYTQ5NDcxNzNiOWQ0MzAwYmYxOScsXG4gICAgICAgICdhZWVmZTkzNzU2YjUzNDBkMmYzYTQ5NThhN2FiYmY1ZTAxNDZlNzdmNjI5NWEwN2I2NzFjZGMxY2MxMDdjZWZkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzE0NmE3NzhjMDQ2NzBjMmY5MWIwMGFmNDY4MGRmYThiY2UzNDkwNzE3ZDU4YmE4ODlkZGI1OTI4MzY2NjQyYmUnLFxuICAgICAgICAnYjMxOGUwZWMzMzU0MDI4YWRkNjY5ODI3ZjlkNGIyODcwYWFhOTcxZDJmN2U1ZWQxZDBiMjk3NDgzZDgzZWZkMCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmYTUwYzBmNjFkMjJlNWYwN2UzYWNlYmIxYWEwN2IxMjhkMDAxMjIwOWEyOGI5Nzc2ZDc2YTg3OTMxODBlZWY5JyxcbiAgICAgICAgJzZiODRjNjkyMjM5N2ViYTliNzJjZDI4NzIyODFhNjhhNWU2ODMyOTNhNTdhMjEzYjM4Y2Q4ZDdkM2Y0ZjI4MTEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZGExZDYxZDBjYTcyMWExMWIxYTViZjZiN2Q4OGU4NDIxYTI4OGFiNWQ1YmJhNTIyMGU1M2QzMmI1ZjA2N2VjMicsXG4gICAgICAgICc4MTU3ZjU1YTdjOTkzMDZjNzljMDc2NjE2MWM5MWUyOTY2YTczODk5ZDI3OWI0OGE2NTVmYmEwZjFhZDgzNmYxJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2E4ZTI4MmZmMGM5NzA2OTA3MjE1ZmY5OGU4ZmQ0MTY2MTUzMTFkZTA0NDZmMWUwNjJhNzNiMDYxMGQwNjRlMTMnLFxuICAgICAgICAnN2Y5NzM1NWI4ZGI4MWMwOWFiZmI3ZjNjNWIyNTE1ODg4YjY3OWEzZTUwZGQ2YmQ2Y2VmN2M3MzExMWY0Y2MwYydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxNzRhNTNiOWM5YTI4NTg3MmQzOWU1NmU2OTEzY2FiMTVkNTliMWZhNTEyNTA4YzAyMmYzODJkZTgzMTk0OTdjJyxcbiAgICAgICAgJ2NjYzlkYzM3YWJmYzljMTY1N2I0MTU1ZjJjNDdmOWU2NjQ2YjNhMWQ4Y2I5ODU0MzgzZGExM2FjMDc5YWZhNzMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOTU5Mzk2OTgxOTQzNzg1YzNkM2U1N2VkZjUwMThjZGJlMDM5ZTczMGU0OTE4YjNkODg0ZmRmZjA5NDc1YjdiYScsXG4gICAgICAgICcyZTdlNTUyODg4YzMzMWRkOGJhMDM4NmE0YjljZDY4NDljNjUzZjY0Yzg3MDkzODVlOWI4YWJmODc1MjRmMmZkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2QyYTYzYTUwYWU0MDFlNTZkNjQ1YTExNTNiMTA5YThmY2NhMGE0M2Q1NjFmYmEyZGJiNTEzNDBjOWQ4MmIxNTEnLFxuICAgICAgICAnZTgyZDg2ZmI2NDQzZmNiNzU2NWFlZTU4YjI5NDgyMjBhNzBmNzUwYWY0ODRjYTUyZDQxNDIxNzRkY2Y4OTQwNSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc2NDU4N2UyMzM1NDcxZWI4OTBlZTc4OTZkN2NmZGM4NjZiYWNiZGJkMzgzOTMxN2IzNDM2ZjliNDU2MTdlMDczJyxcbiAgICAgICAgJ2Q5OWZjZGQ1YmY2OTAyZTJhZTk2ZGQ2NDQ3YzI5OWExODViOTBhMzkxMzNhZWFiMzU4Mjk5ZTVlOWZhZjY1ODknXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnODQ4MWJkZTBlNGU0ZDg4NWIzYTU0NmQzZTU0OWRlMDQyZjBhYTZjZWEyNTBlN2ZkMzU4ZDZjODZkZDQ1ZTQ1OCcsXG4gICAgICAgICczOGVlN2I4Y2JhNTQwNGRkODRhMjViZjM5Y2VjYjJjYTkwMGE3OWM0MmIyNjJlNTU2ZDY0YjFiNTk3NzkwNTdlJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzEzNDY0YTU3YTc4MTAyYWE2MmI2OTc5YWU4MTdmNDYzN2ZmY2ZlZDNjNGIxY2UzMGJjZDYzMDNmNmNhZjY2NmInLFxuICAgICAgICAnNjliZTE1OTAwNDYxNDU4MGVmN2U0MzM0NTNjY2IwY2E0OGYzMDBhODFkMDk0MmUxM2Y0OTVhOTA3ZjZlY2MyNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdiYzRhOWRmNWI3MTNmZTJlOWFlZjQzMGJjYzFkYzk3YTBjZDljY2VkZTJmMjg1ODhjYWRhM2EwZDJkODNmMzY2JyxcbiAgICAgICAgJ2QzYTgxY2E2ZTc4NWMwNjM4MzkzN2FkZjRiNzk4Y2FhNmU4YTlmYmZhNTQ3YjE2ZDc1OGQ2NjY1ODFmMzNjMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4YzI4YTk3YmY4Mjk4YmMwZDIzZDhjNzQ5NDUyYTMyZTY5NGI2NWUzMGE5NDcyYTM5NTRhYjMwZmU1MzI0Y2FhJyxcbiAgICAgICAgJzQwYTMwNDYzYTMzMDUxOTMzNzhmZWRmMzFmN2NjMGViN2FlNzg0ZjA0NTFjYjk0NTllNzFkYzczY2JlZjk0ODInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOGVhOTY2NjEzOTUyN2E4YzFkZDk0Y2U0ZjA3MWZkMjNjOGIzNTBjNWE0YmIzMzc0OGM0YmExMTFmYWNjYWUwJyxcbiAgICAgICAgJzYyMGVmYWJiYzhlZTI3ODJlMjRlN2MwY2ZiOTVjNWQ3MzViNzgzYmU5Y2YwZjhlOTU1YWYzNGEzMGU2MmI5NDUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZGQzNjI1ZmFlZjViYTA2MDc0NjY5NzE2YmJkMzc4OGQ4OWJkZGU4MTU5NTk5NjgwOTJmNzZjYzRlYjlhOTc4NycsXG4gICAgICAgICc3YTE4OGZhMzUyMGUzMGQ0NjFkYTI1MDEwNDU3MzFjYTk0MTQ2MTk4Mjg4MzM5NTkzN2Y2OGQwMGM2NDRhNTczJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2Y3MTBkNzlkOWViOTYyMjk3ZTRmNjIzMmI0MGU4ZjdmZWIyYmM2MzgxNDYxNGQ2OTJjMTJkZTc1MjQwODIyMWUnLFxuICAgICAgICAnZWE5OGU2NzIzMmQzYjMyOTVkM2I1MzU1MzIxMTVjY2FjODYxMmM3MjE4NTE2MTc1MjZhZTQ3YTljNzdiZmM4MidcbiAgICAgIF1cbiAgICBdXG4gIH0sXG4gIG5hZjoge1xuICAgIHduZDogNyxcbiAgICBwb2ludHM6IFtcbiAgICAgIFtcbiAgICAgICAgJ2Y5MzA4YTAxOTI1OGMzMTA0OTM0NGY4NWY4OWQ1MjI5YjUzMWM4NDU4MzZmOTliMDg2MDFmMTEzYmNlMDM2ZjknLFxuICAgICAgICAnMzg4ZjdiMGY2MzJkZTgxNDBmZTMzN2U2MmEzN2YzNTY2NTAwYTk5OTM0YzIyMzFiNmNiOWZkNzU4NGI4ZTY3MidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyZjhiZGU0ZDFhMDcyMDkzNTViNGE3MjUwYTVjNTEyOGU4OGI4NGJkZGM2MTlhYjdjYmE4ZDU2OWIyNDBlZmU0JyxcbiAgICAgICAgJ2Q4YWMyMjI2MzZlNWUzZDZkNGRiYTlkZGE2YzljNDI2Zjc4ODI3MWJhYjBkNjg0MGRjYTg3ZDNhYTZhYzYyZDYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNWNiZGYwNjQ2ZTVkYjRlYWEzOThmMzY1ZjJlYTdhMGUzZDQxOWI3ZTAzMzBlMzljZTkyYmRkZWRjYWM0ZjliYycsXG4gICAgICAgICc2YWViY2E0MGJhMjU1OTYwYTMxNzhkNmQ4NjFhNTRkYmE4MTNkMGI4MTNmZGU3YjVhNTA4MjYyODA4NzI2NGRhJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2FjZDQ4NGUyZjBjN2Y2NTMwOWFkMTc4YTlmNTU5YWJkZTA5Nzk2OTc0YzU3ZTcxNGMzNWYxMTBkZmMyN2NjYmUnLFxuICAgICAgICAnY2MzMzg5MjFiMGE3ZDlmZDY0MzgwOTcxNzYzYjYxZTlhZGQ4ODhhNDM3NWY4ZTBmMDVjYzI2MmFjNjRmOWMzNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3NzRhZTdmODU4YTk0MTFlNWVmNDI0NmI3MGM2NWFhYzU2NDk5ODBiZTVjMTc4OTFiYmVjMTc4OTVkYTAwOGNiJyxcbiAgICAgICAgJ2Q5ODRhMDMyZWI2YjVlMTkwMjQzZGQ1NmQ3YjdiMzY1MzcyZGIxZTJkZmY5ZDZhODMwMWQ3NGM5Yzk1M2M2MWInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZjI4NzczYzJkOTc1Mjg4YmM3ZDFkMjA1YzM3NDg2NTFiMDc1ZmJjNjYxMGU1OGNkZGVlZGRmOGYxOTQwNWFhOCcsXG4gICAgICAgICdhYjA5MDJlOGQ4ODBhODk3NTgyMTJlYjY1Y2RhZjQ3M2ExYTA2ZGE1MjFmYTkxZjI5YjVjYjUyZGIwM2VkODEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDc5MjRkNGY3ZDQzZWE5NjVhNDY1YWUzMDk1ZmY0MTEzMWU1OTQ2ZjNjODVmNzllNDRhZGJjZjhlMjdlMDgwZScsXG4gICAgICAgICc1ODFlMjg3MmE4NmM3MmE2ODM4NDJlYzIyOGNjNmRlZmVhNDBhZjJiZDg5NmQzYTVjNTA0ZGM5ZmY2YTI2YjU4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2RlZmRlYTRjZGI2Nzc3NTBhNDIwZmVlODA3ZWFjZjIxZWI5ODk4YWU3OWI5NzY4NzY2ZTRmYWEwNGEyZDRhMzQnLFxuICAgICAgICAnNDIxMWFiMDY5NDYzNTE2OGU5OTdiMGVhZDJhOTNkYWVjZWQxZjRhMDRhOTVjMGY2Y2ZiMTk5ZjY5ZTU2ZWI3NydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyYjRlYTBhNzk3YTQ0M2QyOTNlZjVjZmY0NDRmNDk3OWYwNmFjZmViZDdlODZkMjc3NDc1NjU2MTM4Mzg1YjZjJyxcbiAgICAgICAgJzg1ZTg5YmMwMzc5NDVkOTNiMzQzMDgzYjVhMWM4NjEzMWEwMWY2MGM1MDI2OTc2M2I1NzBjODU0ZTVjMDliN2EnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzUyYmJmNGE0Y2RkMTI1NjRmOTNmYTMzMmNlMzMzMzAxZDlhZDQwMjcxZjgxMDcxODEzNDBhZWYyNWJlNTlkNScsXG4gICAgICAgICczMjFlYjQwNzUzNDhmNTM0ZDU5YzE4MjU5ZGRhM2UxZjRhMWIzYjJlNzFiMTAzOWM2N2JkM2Q4YmNmODE5OThjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzJmYTIxMDRkNmIzOGQxMWIwMjMwMDEwNTU5ODc5MTI0ZTQyYWI4ZGZlZmY1ZmYyOWRjOWNkYWRkNGVjYWNjM2YnLFxuICAgICAgICAnMmRlMTA2ODI5NWRkODY1YjY0NTY5MzM1YmQ1ZGQ4MDE4MWQ3MGVjZmM4ODI2NDg0MjNiYTc2YjUzMmI3ZDY3J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzkyNDgyNzliMDliNGQ2OGRhYjIxYTliMDY2ZWRkYTgzMjYzYzNkODRlMDk1NzJlMjY5Y2EwY2Q3ZjU0NTM3MTQnLFxuICAgICAgICAnNzMwMTZmN2JmMjM0YWFkZTVkMWFhNzFiZGVhMmIxZmYzZmMwZGUyYTg4NzkxMmZmZTU0YTMyY2U5N2NiMzQwMidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkYWVkNGYyYmUzYThiZjI3OGU3MDEzMmZiMGJlYjc1MjJmNTcwZTE0NGJmNjE1YzA3ZTk5NmQ0NDNkZWU4NzI5JyxcbiAgICAgICAgJ2E2OWRjZTRhN2Q2Yzk4ZThkNGExYWNhODdlZjhkNzAwM2Y4M2MyMzBmM2FmYTcyNmFiNDBlNTIyOTBiZTFjNTUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYzQ0ZDEyYzcwNjVkODEyZThhY2YyOGQ3Y2JiMTlmOTAxMWVjZDllOWZkZjI4MWIwZTZhM2I1ZTg3ZDIyZTdkYicsXG4gICAgICAgICcyMTE5YTQ2MGNlMzI2Y2RjNzZjNDU5MjZjOTgyZmRhYzBlMTA2ZTg2MWVkZjYxYzVhMDM5MDYzZjBlMGU2NDgyJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzZhMjQ1YmY2ZGM2OTg1MDRjODlhMjBjZmRlZDYwODUzMTUyYjY5NTMzNmMyODA2M2I2MWM2NWNiZDI2OWU2YjQnLFxuICAgICAgICAnZTAyMmNmNDJjMmJkNGE3MDhiM2Y1MTI2ZjE2YTI0YWQ4YjMzYmE0OGQwNDIzYjZlZmQ1ZTYzNDgxMDBkOGE4MidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxNjk3ZmZhNmZkOWRlNjI3YzA3N2UzZDJmZTU0MTA4NGNlMTMzMDBiMGJlYzExNDZmOTVhZTU3ZjBkMGJkNmE1JyxcbiAgICAgICAgJ2I5YzM5OGYxODY4MDZmNWQyNzU2MTUwNmU0NTU3NDMzYTJjZjE1MDA5ZTQ5OGFlN2FkZWU5ZDYzZDAxYjIzOTYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNjA1YmRiMDE5OTgxNzE4Yjk4NmQwZjA3ZTgzNGNiMGQ5ZGViODM2MGZmYjdmNjFkZjk4MjM0NWVmMjdhNzQ3OScsXG4gICAgICAgICcyOTcyZDJkZTRmOGQyMDY4MWE3OGQ5M2VjOTZmZTIzYzI2YmZhZTg0ZmIxNGRiNDNiMDFlMWU5MDU2YjhjNDknXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNjJkMTRkYWI0MTUwYmY0OTc0MDJmZGM0NWEyMTVlMTBkY2IwMWMzNTQ5NTliMTBjZmUzMWM3ZTlkODdmZjMzZCcsXG4gICAgICAgICc4MGZjMDZiZDhjYzViMDEwOTgwODhhMTk1MGVlZDBkYjAxYWExMzI5NjdhYjQ3MjIzNWY1NjQyNDgzYjI1ZWFmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzgwYzYwYWQwMDQwZjI3ZGFkZTViNGIwNmM0MDhlNTZiMmM1MGU5ZjU2YjliOGI0MjVlNTU1YzJmODYzMDhiNmYnLFxuICAgICAgICAnMWMzODMwM2YxY2M1YzMwZjI2ZTY2YmFkN2ZlNzJmNzBhNjVlZWQ0Y2JlNzAyNGViMWFhMDFmNTY0MzBiZDU3YSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3YTkzNzVhZDYxNjdhZDU0YWE3NGM2MzQ4Y2M1NGQzNDRjYzVkYzk0ODdkODQ3MDQ5ZDVlYWJiMGZhMDNjOGZiJyxcbiAgICAgICAgJ2QwZTNmYTllY2E4NzI2OTA5NTU5ZTBkNzkyNjkwNDZiZGM1OWVhMTBjNzBjZTJiMDJkNDk5ZWMyMjRkYzdmNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkNTI4ZWNkOWI2OTZiNTRjOTA3YTllZDA0NTQ0N2E3OWJiNDA4ZWMzOWI2OGRmNTA0YmI1MWY0NTliYzNmZmM5JyxcbiAgICAgICAgJ2VlY2Y0MTI1MzEzNmU1Zjk5OTY2ZjIxODgxZmQ2NTZlYmM0MzQ1NDA1YzUyMGRiYzA2MzQ2NWI1MjE0MDk5MzMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNDkzNzBhNGI1ZjQzNDEyZWEyNWY1MTRlOGVjZGFkMDUyNjYxMTVlNGE3ZWNiMTM4NzIzMTgwOGY4YjQ1OTYzJyxcbiAgICAgICAgJzc1OGYzZjQxYWZkNmVkNDI4YjMwODFiMDUxMmZkNjJhNTRjM2YzYWZiYjViNjc2NGI2NTMwNTJhMTI5NDljOWEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzdmMjMwOTM2ZWU4OGNiYmQ3M2RmOTMwZDY0NzAyZWY4ODFkODExZTBlMTQ5OGUyZjFjMTNlYjFmYzM0NWQ3NCcsXG4gICAgICAgICc5NThlZjQyYTc4ODZiNjQwMGEwODI2NmU5YmExYjM3ODk2Yzk1MzMwZDk3MDc3Y2JiZThlYjNjNzY3MWM2MGQ2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2YyZGFjOTkxY2M0Y2U0YjllYTQ0ODg3ZTVjN2MwYmNlNThjODAwNzRhYjlkNGRiYWViMjg1MzFiNzczOWY1MzAnLFxuICAgICAgICAnZTBkZWRjOWIzYjJmOGRhZDRkYTFmMzJkZWMyNTMxZGY5ZWI1ZmJlYjA1OThlNGZkMWExMTdkYmE3MDNhM2MzNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc0NjNiM2Q5ZjY2MjYyMWZiMWI0YmU4ZmJiZTI1MjAxMjVhMjE2Y2RmYzlkYWUzZGViY2JhNDg1MGM2OTBkNDViJyxcbiAgICAgICAgJzVlZDQzMGQ3OGMyOTZjMzU0MzExNDMwNmRkODYyMmQ3YzYyMmUyN2M5NzBhMWRlMzFjYjM3N2IwMWFmNzMwN2UnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZjE2ZjgwNDI0NGU0NmUyYTA5MjMyZDRhZmYzYjU5OTc2Yjk4ZmFjMTQzMjhhMmQxYTMyNDk2YjQ5OTk4ZjI0NycsXG4gICAgICAgICdjZWRhYmQ5YjgyMjAzZjdlMTNkMjA2ZmNkZjRlMzNkOTJhNmM1M2MyNmU1Y2NlMjZkNjU3OTk2MmM0ZTMxZGY2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2NhZjc1NDI3MmRjODQ1NjNiMDM1MmI3YTE0MzExYWY1NWQyNDUzMTVhY2UyN2M2NTM2OWUxNWY3MTUxZDQxZDEnLFxuICAgICAgICAnY2I0NzQ2NjBlZjM1ZjVmMmE0MWI2NDNmYTVlNDYwNTc1ZjRmYTliNzk2MjIzMmE1YzMyZjkwODMxOGEwNDQ3NidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyNjAwY2E0YjI4MmNiOTg2Zjg1ZDBmMTcwOTk3OWQ4YjQ0YTA5YzA3Y2I4NmQ3YzEyNDQ5N2JjODZmMDgyMTIwJyxcbiAgICAgICAgJzQxMTliODg3NTNjMTViZDZhNjkzYjAzZmNkZGJiNDVkNWFjNmJlNzRhYjVmMGVmNDRiMGJlOTQ3NWE3ZTRiNDAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzYzNWNhNzJkN2U4NDMyYzMzOGVjNTNjZDEyMjIwYmMwMWM0ODY4NWUyNGY3ZGM4YzYwMmE3NzQ2OTk4ZTQzNScsXG4gICAgICAgICc5MWI2NDk2MDk0ODlkNjEzZDFkNWU1OTBmNzhlNmQ3NGVjZmMwNjFkNTcwNDhiYWQ5ZTc2ZjMwMmM1YjljNjEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzU0ZTMyMzlmMzI1NTcwY2RiYmY0YTg3ZGVlZThhNjZiN2YyYjMzNDc5ZDQ2OGZiYzFhNTA3NDNiZjU2Y2MxOCcsXG4gICAgICAgICc2NzNmYjg2ZTViZGEzMGZiM2NkMGVkMzA0ZWE0OWEwMjNlZTMzZDAxOTdhNjk1ZDBjNWQ5ODA5M2M1MzY2ODMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTNlNmJkMTA3MWExZTk2YWZmNTc4NTljODJkNTcwZjAzMzA4MDA2NjFkMWM5NTJmOWZlMjY5NDY5MWQ5YjllOCcsXG4gICAgICAgICc1OWM5ZTBiYmEzOTRlNzZmNDBjMGFhNTgzNzlhM2NiNmE1YTIyODM5OTNlOTBjNDE2NzAwMmFmNDkyMGUzN2Y1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzE4NmI0ODNkMDU2YTAzMzgyNmFlNzNkODhmNzMyOTg1YzRjY2IxZjMyYmEzNWY0YjRjYzQ3ZmRjZjA0YWE2ZWInLFxuICAgICAgICAnM2I5NTJkMzJjNjdjZjc3ZTJlMTc0NDZlMjA0MTgwYWIyMWZiODA5MDg5NTEzOGI0YTRhNzk3Zjg2ZTgwODg4YidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkZjlkNzBhNmI5ODc2Y2U1NDRjOTg1NjFmNGJlNGY3MjU0NDJlNmQyYjczN2Q5YzkxYTgzMjE3MjRjZTA5NjNmJyxcbiAgICAgICAgJzU1ZWIyZGFmZDg0ZDZjY2Q1Zjg2MmI3ODVkYzM5ZDRhYjE1NzIyMjcyMGVmOWRhMjE3YjhjNDVjZjJiYTI0MTcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNWVkZDVjYzIzYzUxZTg3YTQ5N2NhODE1ZDVkY2UwZjhhYjUyNTU0Zjg0OWVkODk5NWRlNjRjNWYzNGNlNzE0MycsXG4gICAgICAgICdlZmFlOWM4ZGJjMTQxMzA2NjFlOGNlYzAzMGM4OWFkMGMxM2M2NmMwZDE3YTI5MDVjZGM3MDZhYjczOTlhODY4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzI5MDc5OGMyYjY0NzY4MzBkYTEyZmUwMjI4N2U5ZTc3N2FhM2ZiYTFjMzU1YjE3YTcyMmQzNjJmODQ2MTRmYmEnLFxuICAgICAgICAnZTM4ZGE3NmRjZDQ0MDYyMTk4OGQwMGJjZjc5YWYyNWQ1YjI5YzA5NGRiMmEyMzE0NmQwMDNhZmQ0MTk0M2U3YSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhZjNjNDIzYTk1ZDlmNWIzMDU0NzU0ZWZhMTUwYWMzOWNkMjk1NTJmZTM2MDI1NzM2MmRmZGVjZWY0MDUzYjQ1JyxcbiAgICAgICAgJ2Y5OGEzZmQ4MzFlYjJiNzQ5YTkzYjBlNmYzNWNmYjQwYzhjZDVhYTY2N2ExNTU4MWJjMmZlZGVkNDk4ZmQ5YzYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzY2ZGJiMjRkMTM0ZTc0NWNjY2FhMjhjOTliZjI3NDkwNmJiNjZiMjZkY2Y5OGRmOGQyZmVkNTBkODg0MjQ5YScsXG4gICAgICAgICc3NDRiMTE1MmVhY2JlNWUzOGRjYzg4Nzk4MGRhMzhiODk3NTg0YTY1ZmEwNmNlZGQyYzkyNGY5N2NiYWM1OTk2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzU5ZGJmNDZmOGM5NDc1OWJhMjEyNzdjMzM3ODRmNDE2NDVmN2I0NGY2YzU5NmE1OGNlOTJlNjY2MTkxYWJlM2UnLFxuICAgICAgICAnYzUzNGFkNDQxNzVmYmMzMDBmNGVhNmNlNjQ4MzA5YTA0MmNlNzM5YTc5MTk3OThjZDg1ZTIxNmM0YTMwN2Y2ZSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmMTNhZGE5NTEwM2M0NTM3MzA1ZTY5MWU3NGU5YTRhOGRkNjQ3ZTcxMWE5NWU3M2NiNjJkYzYwMThjZmQ4N2I4JyxcbiAgICAgICAgJ2UxMzgxN2I0NGVlMTRkZTY2M2JmNGJjODA4MzQxZjMyNjk0OWUyMWE2YTc1YzI1NzA3Nzg0MTliZGFmNTczM2QnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzc1NGI0ZmEwZThhY2VkMDZkNDE2N2EyYzU5Y2NhNGNkYTE4NjljMDZlYmFkZmI2NDg4NTUwMDE1YTg4NTIyYycsXG4gICAgICAgICczMGU5M2U4NjRlNjY5ZDgyMjI0Yjk2N2MzMDIwYjhmYThkMWU0ZTM1MGI2Y2JjYzUzN2E0OGI1Nzg0MTE2M2EyJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzk0OGRjYWRmNTk5MGUwNDhhYTM4NzRkNDZhYmVmOWQ3MDE4NThmOTVkZTgwNDFkMmE2ODI4Yzk5ZTIyNjI1MTknLFxuICAgICAgICAnZTQ5MWE0MjUzN2Y2ZTU5N2Q1ZDI4YTMyMjRiMWJjMjVkZjkxNTRlZmJkMmVmMWQyY2JiYTJjYWU1MzQ3ZDU3ZSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3OTYyNDE0NDUwYzc2YzE2ODljN2I0OGY4MjAyZWMzN2ZiMjI0Y2Y1YWMwYmZhMTU3MDMyOGE4YTNkN2M3N2FiJyxcbiAgICAgICAgJzEwMGI2MTBlYzRmZmI0NzYwZDVjMWZjMTMzZWY2ZjZiMTI1MDdhMDUxZjA0YWM1NzYwYWZhNWIyOWRiODM0MzcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzUxNDA4NzgzNDk2NGI1NGIxNWIxNjA2NDRkOTE1NDg1YTE2OTc3MjI1Yjg4NDdiYjBkZDA4NTEzN2VjNDdjYScsXG4gICAgICAgICdlZjBhZmJiMjA1NjIwNTQ0OGUxNjUyYzQ4ZTgxMjdmYzYwMzllNzdjMTVjMjM3OGI3ZTdkMTVhMGRlMjkzMzExJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2QzY2MzMGFkNmI0ODNlNGJjNzljZTJjOWRkOGJjNTQ5OTNlOTQ3ZWI4ZGY3ODdiNDQyOTQzZDNmN2I1MjdlYWYnLFxuICAgICAgICAnOGIzNzhhMjJkODI3Mjc4ZDg5YzVlOWJlOGY5NTA4YWUzYzJhZDQ2MjkwMzU4NjMwYWZiMzRkYjA0ZWVkZTBhNCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxNjI0ZDg0NzgwNzMyODYwY2UxYzc4ZmNiZmVmZTA4YjJiMjk4MjNkYjkxM2Y2NDkzOTc1YmEwZmY0ODQ3NjEwJyxcbiAgICAgICAgJzY4NjUxY2Y5YjZkYTkwM2UwOTE0NDQ4YzZjZDlkNGNhODk2ODc4ZjUyODJiZTRjOGNjMDZlMmE0MDQwNzg1NzUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzMzY2U4MGRhOTU1YThhMjY5MDJjOTU2MzNlNjJhOTg1MTkyNDc0YjVhZjIwN2RhNmRmN2I0ZmQ1ZmM2MWNkNCcsXG4gICAgICAgICdmNTQzNWEyYmQyYmFkZjdkNDg1YTRkOGI4ZGI5ZmNjZTNlMWVmOGUwMjAxZTQ1NzhjNTQ2NzNiYzFkYzVlYTFkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzE1ZDk0NDEyNTQ5NDUwNjRjZjFhMWMzM2JiZDNiNDlmODk2NmM1MDkyMTcxZTY5OWVmMjU4ZGZhYjgxYzA0NWMnLFxuICAgICAgICAnZDU2ZWIzMGI2OTQ2M2U3MjM0ZjUxMzdiNzNiODQxNzc0MzQ4MDBiYWNlYmZjNjg1ZmMzN2JiZTllZmU0MDcwZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhMWQwZmNmMmVjOWRlNjc1YjYxMjEzNmU1Y2U3MGQyNzFjMjE0MTdjOWQyYjhhYWFhYzEzODU5OWQwNzE3OTQwJyxcbiAgICAgICAgJ2VkZDc3ZjUwYmNiNWEzY2FiMmU5MDczNzMwOTY2N2YyNjQxNDYyYTU0MDcwZjNkNTE5MjEyZDM5YzE5N2E2MjknXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTIyZmJlMTVjMGFmOGNjYzU3ODBjMDczNWY4NGRiZTlhNzkwYmFkZWU4MjQ1YzA2YzdjYTM3MzMxY2IzNjk4MCcsXG4gICAgICAgICdhODU1YmFiYWQ1Y2Q2MGM4OGI0MzBhNjlmNTNhMWE3YTM4Mjg5MTU0OTY0Nzk5YmU0M2QwNmQ3N2QzMWRhMDYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzExMDkxZGQ5ODYwZThlMjBlZTEzNDczYzExNTVmNWY2OTYzNWUzOTQ3MDRlYWE3NDAwOTQ1MjI0NmNmYTliMycsXG4gICAgICAgICc2NmRiNjU2Zjg3ZDFmMDRmZmZkMWYwNDc4OGMwNjgzMDg3MWVjNWE2NGZlZWU2ODViZDgwZjBiMTI4NmQ4Mzc0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzM0YzFmZDA0ZDMwMWJlODliMzFjMDQ0MmQzZTZhYzI0ODgzOTI4YjQ1YTkzNDA3ODE4NjdkNDIzMmVjMmRiZGYnLFxuICAgICAgICAnOTQxNDY4NWU5N2IxYjU5NTRiZDQ2ZjczMDE3NDEzNmQ1N2YxY2VlYjQ4NzQ0M2RjNTMyMTg1N2JhNzNhYmVlJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2YyMTllYTVkNmI1NDcwMWMxYzE0ZGU1YjU1N2ViNDJhOGQxM2YzYWJiY2QwOGFmZmNjMmE1ZTZiMDQ5YjhkNjMnLFxuICAgICAgICAnNGNiOTU5NTdlODNkNDBiMGY3M2FmNDU0NGNjY2Y2YjFmNGIwOGQzYzA3YjI3ZmI4ZDhjMjk2MmE0MDA3NjZkMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkN2I4NzQwZjc0YThmYmFhYjFmNjgzZGI4ZjQ1ZGUyNjU0M2E1NDkwYmNhNjI3MDg3MjM2OTEyNDY5YTBiNDQ4JyxcbiAgICAgICAgJ2ZhNzc5NjgxMjhkOWM5MmVlMTAxMGYzMzdhZDQ3MTdlZmYxNWRiNWVkM2MwNDliMzQxMWUwMzE1ZWFhNDU5M2InXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzJkMzFjMjIyZjhmNmYwZWY4NmY3Yzk4ZDNhMzMzNWVhZDViY2QzMmFiZGQ5NDI4OWZlNGQzMDkxYWE4MjRiZicsXG4gICAgICAgICc1ZjMwMzJmNTg5MjE1NmUzOWNjZDNkNzkxNWI5ZTFkYTJlNmRhYzllNmYyNmU5NjExMThkMTRiODQ2MmUxNjYxJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc0NjFmMzcxOTE0YWIzMjY3MTA0NWExNTVkOTgzMWVhODc5M2Q3N2NkNTk1OTJjNDM0MGY4NmNiYzE4MzQ3YjUnLFxuICAgICAgICAnOGVjMGJhMjM4Yjk2YmVjMGNiZGRkY2FlMGFhNDQyNTQyZWVlMWZmNTBjOTg2ZWE2YjM5ODQ3YjNjYzA5MmZmNidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlZTA3OWFkYjFkZjE4NjAwNzQzNTZhMjVhYTM4MjA2YTZkNzE2YjJjM2U2NzQ1M2QyODc2OThiYWQ3YjJiMmQ2JyxcbiAgICAgICAgJzhkYzI0MTJhYWZlM2JlNWM0YzVmMzdlMGVjYzVmOWY2YTQ0Njk4OWFmMDRjNGUyNWViYWFjNDc5ZWMxYzhjMWUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMTZlYzkzZTQ0N2VjODNmMDQ2N2IxODMwMmVlNjIwZjdlNjVkZTMzMTg3NGM5ZGM3MmJmZDg2MTZiYTlkYTZiNScsXG4gICAgICAgICc1ZTQ2MzExNTBlNjJmYjQwZDBlOGMyYTdjYTU4MDRhMzlkNTgxODZhNTBlNDk3MTM5NjI2Nzc4ZTI1YjA2NzRkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2VhYTVmOTgwYzI0NWY2ZjAzODk3ODI5MGFmYTcwYjZiZDg4NTU4OTdmOThiNmFhNDg1Yjk2MDY1ZDUzN2JkOTknLFxuICAgICAgICAnZjY1ZjVkM2UyOTJjMmUwODE5YTUyODM5MWM5OTQ2MjRkNzg0ODY5ZDdlNmVhNjdmYjE4MDQxMDI0ZWRjMDdkYydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3OGM5NDA3NTQ0YWMxMzI2OTJlZTE5MTBhMDI0Mzk5NThhZTA0ODc3MTUxMzQyZWE5NmM0YjZiMzVhNDlmNTEnLFxuICAgICAgICAnZjNlMDMxOTE2OWViOWI4NWQ1NDA0Nzk1NTM5YTVlNjhmYTFmYmQ1ODNjMDY0ZDI0NjJiNjc1ZjE5NGEzZGRiNCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc0OTRmNGJlMjE5YTFhNzcwMTZkY2Q4Mzg0MzFhZWEwMDAxY2RjOGFlN2E2ZmM2ODg3MjY1NzhkOTcwMjg1N2E1JyxcbiAgICAgICAgJzQyMjQyYTk2OTI4M2E1ZjMzOWJhN2YwNzVlMzZiYTJhZjkyNWNlMzBkNzY3ZWQ2ZTU1ZjRiMDMxODgwZDU2MmMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYTU5OGE4MDMwZGE2ZDg2YzZiYzdmMmY1MTQ0ZWE1NDlkMjgyMTFlYTU4ZmFhNzBlYmY0YzFlNjY1YzFmZTliNScsXG4gICAgICAgICcyMDRiNWQ2Zjg0ODIyYzMwN2U0YjRhNzE0MDczN2FlYzIzZmM2M2I2NWIzNWY4NmExMDAyNmRiZDJkODY0ZTZiJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2M0MTkxNjM2NWFiYjJiNWQwOTE5MmY1ZjJkYmVhZmVjMjA4ZjAyMGYxMjU3MGExODRkYmFkYzNlNTg1OTU5OTcnLFxuICAgICAgICAnNGYxNDM1MWQwMDg3ZWZhNDlkMjQ1YjMyODk4NDk4OWQ1Y2FmOTQ1MGYzNGJmYzBlZDE2ZTk2YjU4ZmE5OTEzJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzg0MWQ2MDYzYTU4NmZhNDc1YTcyNDYwNGRhMDNiYzViOTJhMmUwZDJlMGEzNmFjZmU0YzczYTU1MTQ3NDI4ODEnLFxuICAgICAgICAnNzM4NjdmNTljMDY1OWU4MTkwNGY5YTFjNzU0MzY5OGU2MjU2MmQ2NzQ0YzE2OWNlN2EzNmRlMDFhOGQ2MTU0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzVlOTViYjM5OWE2OTcxZDM3NjAyNjk0N2Y4OWJkZTJmMjgyYjMzODEwOTI4YmU0ZGVkMTEyYWM0ZDcwZTIwZDUnLFxuICAgICAgICAnMzlmMjNmMzY2ODA5MDg1YmVlYmZjNzExODEzMTM3NzVhOTljOWFlZDdkOGJhMzhiMTYxMzg0Yzc0NjAxMjg2NSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczNmU0NjQxYTUzOTQ4ZmQ0NzZjMzlmOGE5OWZkOTc0ZTVlYzA3NTY0YjUzMTVkOGJmOTk0NzFiY2EwZWYyZjY2JyxcbiAgICAgICAgJ2QyNDI0YjFiMWFiZTRlYjgxNjQyMjdiMDg1YzlhYTk0NTZlYTEzNDkzZmQ1NjNlMDZmZDUxY2Y1Njk0Yzc4ZmMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzM2NTgxZWE3YmZiYmIyOTBjMTkxYTJmNTA3YTQxY2Y1NjQzODQyMTcwZTkxNGZhZWFiMjdjMmM1NzlmNzI2JyxcbiAgICAgICAgJ2VhZDEyMTY4NTk1ZmUxYmU5OTI1MjEyOWI2ZTU2YjMzOTFmN2FiMTQxMGNkMWUwZWYzZGNkY2FiZDJmZGEyMjQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOGFiODk4MTZkYWRmZDZiNmExZjI2MzRmY2YwMGVjODQwMzc4MTAyNWVkNjg5MGM0ODQ5NzQyNzA2YmQ0M2VkZScsXG4gICAgICAgICc2ZmRjZWYwOWYyZjZkMGEwNDRlNjU0YWVmNjI0MTM2ZjUwM2Q0NTljM2U4OTg0NTg1OGE0N2E5MTI5Y2RkMjRlJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzFlMzNmMWE3NDZjOWM1Nzc4MTMzMzQ0ZDkyOTlmY2FhMjBiMDkzOGU4YWNmZjI1NDRiYjQwMjg0YjhjNWZiOTQnLFxuICAgICAgICAnNjA2NjAyNTdkZDExYjNhYTljOGVkNjE4ZDI0ZWRmZjIzMDZkMzIwZjFkMDMwMTBlMzNhN2QyMDU3ZjNiM2I2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzg1YjdjMWRjYjNjZWMxYjdlZTdmMzBkZWQ3OWRkMjBhMGVkMWY0Y2MxOGNiY2ZjZmE0MTAzNjFmZDhmMDhmMzEnLFxuICAgICAgICAnM2Q5OGE5Y2RkMDI2ZGQ0M2YzOTA0OGYyNWE4ODQ3ZjRmY2FmYWQxODk1ZDdhNjMzYzZmZWQzYzM1ZTk5OTUxMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyOWRmOWZiZDhkOWU0NjUwOTI3NWY0YjEyNWQ2ZDQ1ZDdmYmU5YTNiODc4YTdhZjg3MmEyODAwNjYxYWM1ZjUxJyxcbiAgICAgICAgJ2I0YzRmZTk5Yzc3NWE2MDZlMmQ4ODYyMTc5MTM5ZmZkYTYxZGM4NjFjMDE5ZTU1Y2QyODc2ZWIyYTI3ZDg0YidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhMGIxY2FlMDZiMGE4NDdhM2ZlYTZlNjcxYWFmOGFkZmRmZTU4Y2EyZjc2ODEwNWM4MDgyYjJlNDQ5ZmNlMjUyJyxcbiAgICAgICAgJ2FlNDM0MTAyZWRkZTA5NThlYzRiMTlkOTE3YTZhMjhlNmI3MmRhMTgzNGFmZjBlNjUwZjA0OTUwM2EyOTZjZjInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNGU4Y2VhZmI5YjNlOWExMzZkYzdmZjY3ZTg0MDI5NWI0OTlkZmIzYjIxMzNlNGJhMTEzZjJlNGMwZTEyMWU1JyxcbiAgICAgICAgJ2NmMjE3NDExOGM4YjZkN2E0YjQ4ZjZkNTM0Y2U1Yzc5NDIyYzA4NmE2MzQ2MDUwMmI4MjdjZTYyYTMyNjY4M2MnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDI0YTQ0ZTA0N2UxOWI2ZjVhZmI4MWM3Y2EyZjY5MDgwYTUwNzY2ODlhMDEwOTE5ZjQyNzI1YzJiNzg5YTMzYicsXG4gICAgICAgICc2ZmI4ZDU1OTFiNDY2ZjhmYzYzZGI1MGYxYzBmMWM2OTAxM2Y5OTY4ODdiODI0NGQyY2RlYzQxN2FmZWE4ZmEzJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2VhMDE2MDZhN2E2YzljZGQyNDlmZGZjZmFjYjk5NTg0MDAxZWRkMjhhYmJhYjc3YjUxMDRlOThlOGUzYjM1ZDQnLFxuICAgICAgICAnMzIyYWY0OTA4YzczMTJiMGNmYmZlMzY5ZjdhN2IzY2RiN2Q0NDk0YmMyODIzNzAwY2ZkNjUyMTg4YTNlYTk4ZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhZjhhZGRiZjJiNjYxYzhhNmM2MzI4NjU1ZWI5NjY1MTI1MjAwN2Q4YzVlYTMxYmU0YWQxOTZkZThjZTIxMzFmJyxcbiAgICAgICAgJzY3NDllNjdjMDI5Yjg1ZjUyYTAzNGVhZmQwOTY4MzZiMjUyMDgxODY4MGUyNmFjOGYzZGZiY2RiNzE3NDk3MDAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTNhZTE5NzQ1NjZjYTA2Y2M1MTZkNDdlMGZiMTY1YTY3NGEzZGFiY2ZjYTE1ZTcyMmYwZTM0NTBmNDU4ODknLFxuICAgICAgICAnMmFlYWJlN2U0NTMxNTEwMTE2MjE3ZjA3YmY0ZDA3MzAwZGU5N2U0ODc0ZjgxZjUzMzQyMGE3MmVlYjBiZDZhNCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc1OTFlZTM1NTMxM2Q5OTcyMWNmNjk5M2ZmZWQxZTNlMzAxOTkzZmYzZWQyNTg4MDIwNzVlYThjZWQzOTdlMjQ2JyxcbiAgICAgICAgJ2IwZWE1NThhMTEzYzMwYmVhNjBmYzQ3NzU0NjBjNzkwMWZmMGIwNTNkMjVjYTJiZGVlZTk4ZjFhNGJlNWQxOTYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMTEzOTZkNTVmZGE1NGM0OWYxOWFhOTczMThkOGRhNjFmYTg1ODRlNDdiMDg0OTQ1MDc3Y2YwMzI1NWI1Mjk4NCcsXG4gICAgICAgICc5OThjNzRhOGNkNDVhYzAxMjg5ZDU4MzNhN2JlYjQ3NDRmZjUzNmIwMWIyNTdiZTRjNTc2N2JlYTkzZWE1N2E0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzNjNWQyYTFiYTM5YzVhMTc5MDAwMDczOGM5ZTBjNDBiOGRjZGZkNTQ2ODc1NGI2NDA1NTQwMTU3ZTAxN2FhN2EnLFxuICAgICAgICAnYjIyODQyNzk5OTVhMzRlMmY5ZDRkZTczOTZmYzE4YjgwZjliOGI5ZmRkMjcwZjY2NjFmNzljYTRjODFiZDI1NydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdjYzg3MDRiOGE2MGEwZGVmYTNhOTlhNzI5OWYyZTljM2ZiYzM5NWFmYjA0YWMwNzg0MjVlZjhhMTc5M2NjMDMwJyxcbiAgICAgICAgJ2JkZDQ2MDM5ZmVlZDE3ODgxZDFlMDg2MmRiMzQ3ZjhjZjM5NWI3NGZjNGJjZGM0ZTk0MGI3NGUzYWMxZjFiMTMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYzUzM2U0ZjdlYTg1NTVhYWNkOTc3N2FjNWNhZDI5Yjk3ZGQ0ZGVmY2NjNTNlZTdlYTIwNDExOWIyODg5YjE5NycsXG4gICAgICAgICc2ZjBhMjU2YmM1ZWZkZjQyOWEyZmI2MjQyZjFhNDNhMmQ5YjkyNWJiNGE0YjNhMjZiYjhlMGY0NWViNTk2MDk2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2MxNGY4ZjJjY2IyN2Q2ZjEwOWY2ZDA4ZDAzY2M5NmE2OWJhOGMzNGVlYzA3YmJjZjU2NmQ0OGUzM2RhNjU5MycsXG4gICAgICAgICdjMzU5ZDY5MjNiYjM5OGY3ZmQ0NDczZTE2ZmUxYzI4NDc1Yjc0MGRkMDk4MDc1ZTZjMGU4NjQ5MTEzZGMzYTM4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2E2Y2JjMzA0NmJjNmE0NTBiYWMyNDc4OWZhMTcxMTVhNGM5NzM5ZWQ3NWY4ZjIxY2U0NDFmNzJlMGI5MGU2ZWYnLFxuICAgICAgICAnMjFhZTdmNDY4MGU4ODliYjEzMDYxOWUyYzBmOTVhMzYwY2ViNTczYzcwNjAzMTM5ODYyYWZkNjE3ZmE5YjlmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzM0N2Q2ZDlhMDJjNDg5MjdlYmZiODZjMTM1OWIxY2FmMTMwYTNjMDI2N2QxMWNlNjM0NGIzOWY5OWQ0M2NjMzgnLFxuICAgICAgICAnNjBlYTdmNjFhMzUzNTI0ZDFjOTg3ZjZlY2VjOTJmMDg2ZDU2NWFiNjg3ODcwY2IxMjY4OWZmMWUzMWM3NDQ0OCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkYTY1NDVkMjE4MWRiOGQ5ODNmN2RjYjM3NWVmNTg2NmQ0N2M2N2IxYmYzMWM4Y2Y4NTVlZjc0MzdiNzI2NTZhJyxcbiAgICAgICAgJzQ5Yjk2NzE1YWI2ODc4YTc5ZTc4ZjA3Y2U1NjgwYzVkNjY3MzA1MWI0OTM1YmQ4OTdmZWE4MjRiNzdkYzIwOGEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYzQwNzQ3Y2M5ZDAxMmNiMWExM2I4MTQ4MzA5YzZkZTdlYzI1ZDY5NDVkNjU3MTQ2YjlkNTk5NGI4ZmViMTExMScsXG4gICAgICAgICc1Y2E1NjA3NTNiZTJhMTJmYzZkZTZjYWYyY2I0ODk1NjVkYjkzNjE1NmI5NTE0ZTFiYjVlODMwMzdlMGZhMmQ0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzRlNDJjOGVjODJjOTk3OThjY2YzYTYxMGJlODcwZTc4MzM4YzdmNzEzMzQ4YmQzNGM4MjAzZWY0MDM3ZjM1MDInLFxuICAgICAgICAnNzU3MWQ3NGVlNWUwZmI5MmE3YThiMzNhMDc3ODMzNDFhNTQ5MjE0NGNjNTRiY2M0MGE5NDQ3MzY5MzYwNjQzNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczNzc1YWI3MDg5YmM2YWY4MjNhYmEyZTFhZjcwYjIzNmQyNTFjYWRiMGM4Njc0MzI4NzUyMmExYjNiMGRlZGVhJyxcbiAgICAgICAgJ2JlNTJkMTA3YmNmYTA5ZDhiY2I5NzM2YTgyOGNmYTdmYWM4ZGIxN2JmN2E3NmEyYzQyYWQ5NjE0MDkwMThjZjcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnY2VlMzFjYmY3ZTM0ZWMzNzlkOTRmYjgxNGQzZDc3NWFkOTU0NTk1ZDEzMTRiYTg4NDY5NTllM2U4MmY3NGUyNicsXG4gICAgICAgICc4ZmQ2NGExNGMwNmI1ODljMjZiOTQ3YWUyYmNmNmJmYTAxNDllZjBiZTE0ZWQ0ZDgwZjQ0OGEwMWM0M2IxYzZkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2I0ZjllYWVhMDliNjkxNzYxOWY2ZWE2YTRlYjU0NjRlZmRkYjU4ZmQ0NWIxZWJlZmNkYzFhMDFkMDhiNDc5ODYnLFxuICAgICAgICAnMzllNWM5OTI1YjVhNTRiMDc0MzNhNGYxOGM2MTcyNmY4YmIxMzFjMDEyY2E1NDJlYjI0YThhYzA3MjAwNjgyYSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkNDI2M2RmYzNkMmRmOTIzYTAxNzlhNDg5NjZkMzBjZTg0ZTI1MTVhZmMzZGNjYzFiNzc5MDc3OTJlYmNjNjBlJyxcbiAgICAgICAgJzYyZGZhZjA3YTBmNzhmZWIzMGUzMGQ2Mjk1ODUzY2UxODllMTI3NzYwYWQ2Y2Y3ZmFlMTY0ZTEyMmEyMDhkNTQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNDg0NTc1MjQ4MjBmYTY1YTRmOGQzNWViNjkzMDg1N2MwMDMyYWNjMGE0YTJkZTQyMjIzM2VlZGE4OTc2MTJjNCcsXG4gICAgICAgICcyNWE3NDhhYjM2Nzk3OWQ5ODczM2MzOGExZmExYzJlN2RjNmNjMDdkYjJkNjBhOWFlN2E3NmFhYTQ5YmQwZjc3J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2RmZWVlZjE4ODExMDFmMmNiMTE2NDRmM2EyYWZkZmMyMDQ1ZTE5OTE5MTUyOTIzZjM2N2ExNzY3YzExY2NlZGEnLFxuICAgICAgICAnZWNmYjcwNTZjZjFkZTA0MmY5NDIwYmFiMzk2NzkzYzBjMzkwYmRlNzRiNGJiZGZmMTZhODNhZTA5YTlhNzUxNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc2ZDdlZjZiMTc1NDNmODM3M2M1NzNmNDRlMWYzODk4MzVkODliY2JjNjA2MmNlZDM2YzgyZGY4M2I4ZmFlODU5JyxcbiAgICAgICAgJ2NkNDUwZWMzMzU0Mzg5ODZkZmVmYTEwYzU3ZmVhOWJjYzUyMWEwOTU5YjJkODBiYmY3NGIxOTBkY2E3MTJkMTAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTc1NjA1ZDU5MTAyYTVhMjY4NDUwMGQzYjk5MWYyZTNmM2M4OGI5MzIyNTU0NzAzNWFmMjVhZjY2ZTA0NTQxZicsXG4gICAgICAgICdmNWM1NDc1NGE4ZjcxZWU1NDBiOWI0ODcyODQ3M2UzMTRmNzI5YWM1MzA4YjA2OTM4MzYwOTkwZTJiZmFkMTI1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2ViOTg2NjBmNGM0ZGZhYTA2YTJiZTQ1M2Q1MDIwYmM5OWEwYzJlNjBhYmUzODg0NTdkZDQzZmVmYjFlZDYyMGMnLFxuICAgICAgICAnNmNiOWE4ODc2ZDljYjg1MjA2MDlhZjNhZGQyNmNkMjBhMGE3Y2Q4YTk0MTExMzFjZTg1ZjQ0MTAwMDk5MjIzZSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxM2U4N2IwMjdkODUxNGQzNTkzOWYyZTY4OTJiMTk5MjIxNTQ1OTY5NDE4ODgzMzZkYzM1NjNlM2I4ZGJhOTQyJyxcbiAgICAgICAgJ2ZlZjVhM2M2ODA1OWE2ZGVjNWQ2MjQxMTRiZjFlOTFhYWMyYjlkYTU2OGQ2YWJlYjI1NzBkNTU2NDZiOGFkZjEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZWUxNjMwMjZlOWZkNmZlMDE3YzM4ZjA2YTViZTZmYzEyNTQyNGIzNzFjZTI3MDhlN2JmNDQ5MTY5MWU1NzY0YScsXG4gICAgICAgICcxYWNiMjUwZjI1NWRkNjFjNDNkOTRjY2M2NzBkMGY1OGY0OWFlM2ZhMTViOTY2MjNlNTQzMGRhMGFkNmM2MmIyJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2IyNjhmNWVmOWFkNTFlNGQ3OGRlM2E3NTBjMmRjODliMWU2MjZkNDM1MDU4Njc5OTk5MzJlNWRiMzNhZjNkODAnLFxuICAgICAgICAnNWYzMTBkNGIzYzk5YjllYmIxOWY3N2Q0MWMxZGVlMDE4Y2YwZDM0ZmQ0MTkxNjE0MDAzZTk0NWExMjE2ZTQyMydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmZjA3ZjMxMThhOWRmMDM1ZTlmYWQ4NWViNmM3YmZlNDJiMDJmMDFjYTk5Y2VlYTNiZjdmZmRiYTkzYzQ3NTBkJyxcbiAgICAgICAgJzQzODEzNmQ2MDNlODU4YTNhNWM0NDBjMzhlY2NiYWRkYzFkMjk0MjExNGUyZWRkZDQ3NDBkMDk4Y2VkMWYwZDgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOGQ4Yjk4NTVjN2MwNTJhMzQxNDZmZDIwZmZiNjU4YmVhNGI5ZjY5ZTBkODI1ZWJlYzE2ZThjM2NlMmI1MjZhMScsXG4gICAgICAgICdjZGI1NTllZWRjMmQ3OWY5MjZiYWY0NGZiODRlYTRkNDRiY2Y1MGZlZTUxZDdjZWIzMGUyZTdmNDYzMDM2NzU4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzUyZGIwYjUzODRkZmJmMDViZmE5ZDQ3MmQ3YWUyNmRmZTRiODUxY2VjYTkxYjFlYmE1NDI2MzE4MGRhMzJiNjMnLFxuICAgICAgICAnYzNiOTk3ZDA1MGVlNWQ0MjNlYmFmNjZhNmRiOWY1N2IzMTgwYzkwMjg3NTY3OWRlOTI0YjY5ZDg0YTdiMzc1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2U2MmY5NDkwZDNkNTFkYTYzOTVlZmQyNGU4MDkxOWNjN2QwZjI5YzNmM2ZhNDhjNmZmZjU0M2JlY2JkNDMzNTInLFxuICAgICAgICAnNmQ4OWFkN2JhNDg3NmIwYjIyYzJjYTI4MGM2ODI4NjJmMzQyYzg1OTFmMWRhZjUxNzBlMDdiZmQ5Y2NhZmE3ZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3ZjMwZWEyNDc2YjM5OWI0OTU3NTA5Yzg4Zjc3ZDAxOTFhZmEyZmY1Y2I3YjE0ZmQ2ZDhlN2Q2NWFhYWIxMTkzJyxcbiAgICAgICAgJ2NhNWVmN2Q0YjIzMWM5NGMzYjE1Mzg5YTVmNjMxMWU5ZGFmZjdiYjY3YjEwM2U5ODgwZWY0YmZmNjM3YWNhZWMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNTA5OGZmMWUxZDlmMTRmYjQ2YTIxMGZhZGE2YzkwM2ZlZjBmYjdiNGExZGQxZDlhYzYwYTAzNjE4MDBiN2EwMCcsXG4gICAgICAgICc5NzMxMTQxZDgxZmM4ZjgwODRkMzdjNmU3NTQyMDA2YjNlZTFiNDBkNjBkZmU1MzYyYTViMTMyZmQxN2RkYzAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzJiNzhjN2RlOWVlNTEyYTcyODk1YmU2YjljYmVmYTZlMmYzYzRjY2NlNDQ1Yzk2YjlmMmM4MWUyNzc4YWQ1OCcsXG4gICAgICAgICdlZTE4NDlmNTEzZGY3MWUzMmVmYzM4OTZlZTI4MjYwYzczYmI4MDU0N2FlMjI3NWJhNDk3MjM3Nzk0Yzg3NTNjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2UyY2I3NGZkZGM4ZTlmYmNkMDc2ZWVmMmE3YzcyYjBjZTM3ZDUwZjA4MjY5ZGZjMDc0YjU4MTU1MDU0N2E0ZjcnLFxuICAgICAgICAnZDNhYTJlZDcxYzlkZDIyNDdhNjJkZjA2MjczNmViMGJhZGRlYTllMzYxMjJkMmJlODY0MWFiY2IwMDVjYzRhNCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4NDM4NDQ3NTY2ZDRkN2JlZGFkYzI5OTQ5NmFiMzU3NDI2MDA5YTM1ZjIzNWNiMTQxYmUwZDk5Y2QxMGFlM2E4JyxcbiAgICAgICAgJ2M0ZTEwMjA5MTY5ODBhNGRhNWQwMWFjNWU2YWQzMzA3MzRlZjBkNzkwNjYzMWM0ZjIzOTA0MjZiMmVkZDc5MWYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNDE2MmQ0ODhiODk0MDIwMzliNTg0YzZmYzZjMzA4ODcwNTg3ZDljNDZmNjYwYjg3OGFiNjVjODJjNzExZDY3ZScsXG4gICAgICAgICc2NzE2M2U5MDMyMzYyODlmNzc2ZjIyYzI1ZmI4YTNhZmMxNzMyZjJiODRiNGU5NWRiZGE0N2FlNWEwODUyNjQ5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzNmYWQzZmE4NGNhZjBmMzRmMGY4OWJmZDJkY2Y1NGZjMTc1ZDc2N2FlYzNlNTA2ODRmM2JhNGE0YmY1ZjY4M2QnLFxuICAgICAgICAnY2QxYmM3Y2I2Y2M0MDdiYjJmMGNhNjQ3YzcxOGE3MzBjZjcxODcyZTdkMGQyYTUzZmEyMGVmY2RmZTYxODI2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzY3NGYyNjAwYTMwMDdhMDA1NjhjMWE3Y2UwNWQwODE2YzFmYjg0YmYxMzcwNzk4ZjFjNjk1MzJmYWViMWE4NmInLFxuICAgICAgICAnMjk5ZDIxZjk0MTNmMzNiM2VkZjQzYjI1NzAwNDU4MGI3MGRiNTdkYTBiMTgyMjU5ZTA5ZWVjYzY5ZTBkMzhhNSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkMzJmNGRhNTRhZGU3NGFiYjgxYjgxNWFkMWZiM2IyNjNkODJkNmM2OTI3MTRiY2ZmODdkMjliZDVlZTlmMDhmJyxcbiAgICAgICAgJ2Y5NDI5ZTczOGI4ZTUzYjk2OGU5OTAxNmMwNTk3MDc3ODJlMTRmNDUzNTM1OWQ1ODJmYzQxNjkxMGIzZWVhODcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzBlNGU2NzA0MzUzODU1NTZlNTkzNjU3MTM1ODQ1ZDM2ZmJiNjkzMWY3MmIwOGNiMWVkOTU0ZjFlM2NlM2ZmNicsXG4gICAgICAgICc0NjJmOWJjZTYxOTg5ODYzODQ5OTM1MDExM2JiYzliMTBhODc4ZDM1ZGE3MDc0MGRjNjk1YTU1OWViODhkYjdiJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2JlMjA2MjAwM2M1MWNjMzAwNDY4MjkwNDMzMGU0ZGVlN2YzZGNkMTBiMDFlNTgwYmYxOTcxYjA0ZDRjYWQyOTcnLFxuICAgICAgICAnNjIxODhiYzQ5ZDYxZTU0Mjg1NzNkNDhhNzRlMWM2NTViMWM2MTA5MDkwNTY4MmEwZDU1NThlZDcyZGNjYjliYydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc5MzE0NDQyM2FjZTM0NTFlZDI5ZTBmYjlhYzJhZjIxMWNiNmU4NGE2MDFkZjU5OTNjNDE5ODU5ZmZmNWRmMDRhJyxcbiAgICAgICAgJzdjMTBkZmIxNjRjMzQyNWY1YzcxYTNmOWQ3OTkyMDM4ZjEwNjUyMjRmNzJiYjlkMWQ5MDJhNmQxMzAzN2I0N2MnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYjAxNWY4MDQ0ZjVmY2JkY2YyMWNhMjZkNmMzNGZiODE5NzgyOTIwNWM3YjdkMmE3Y2I2NjQxOGMxNTdiMTEyYycsXG4gICAgICAgICdhYjhjMWUwODZkMDRlODEzNzQ0YTY1NWIyZGY4ZDVmODNiM2NkYzZmYWEzMDg4YzFkM2FlYTE0NTRlM2ExZDVmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2Q1ZTllMWRhNjQ5ZDk3ZDg5ZTQ4NjgxMTdhNDY1YTNhNGY4YTE4ZGU1N2ExNDBkMzZiM2YyYWYzNDFhMjFiNTInLFxuICAgICAgICAnNGNiMDQ0MzdmMzkxZWQ3MzExMWExM2NjMWQ0ZGQwZGIxNjkzNDY1YzIyNDA0ODBkODk1NWU4NTkyZjI3NDQ3YSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkM2FlNDEwNDdkZDdjYTA2NWRiZjhlZDc3Yjk5MjQzOTk4MzAwNWNkNzJlMTZkNmY5OTZhNTMxNmQzNjk2NmJiJyxcbiAgICAgICAgJ2JkMWFlYjIxYWQyMmViYjIyYTEwZjAzMDM0MTdjNmQ5NjRmOGNkZDdkZjBhY2E2MTRiMTBkYzE0ZDEyNWFjNDYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNDYzZTI3NjNkODg1Zjk1OGZjNjZjZGQyMjgwMGYwYTQ4NzE5N2QwYTgyZTM3N2I0OWY4MGFmODdjODk3YjA2NScsXG4gICAgICAgICdiZmVmYWNkYjBlNWQwZmQ3ZGYzYTMxMWE5NGRlMDYyYjI2YjgwYzYxZmJjOTc1MDhiNzk5OTI2NzFlZjdjYTdmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc5ODVmZGZkMTI3YzA1NjdjNmY1M2VjMWJiNjNlYzMxNThlNTk3YzQwYmZlNzQ3YzgzY2RkZmM5MTA2NDE5MTcnLFxuICAgICAgICAnNjAzYzEyZGFmM2Q5ODYyZWYyYjI1ZmUxZGUyODlhZWQyNGVkMjkxZTBlYzY3MDg3MDNhNWJkNTY3ZjMyZWQwMydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3NGExYWQ2YjVmNzZlMzlkYjJkZDI0OTQxMGVhYzdmOTllNzRjNTljYjgzZDJkMGVkNWZmMTU0M2RhNzcwM2U5JyxcbiAgICAgICAgJ2NjNjE1N2VmMThjOWM2M2NkNjE5M2Q4MzYzMWJiZWEwMDkzZTA5Njg5NDJlOGMzM2Q1NzM3ZmQ3OTBlMGRiMDgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzA2ODJhNTA3MDMzNzVmNjAyZDQxNjY2NGJhMTliN2ZjOWJhYjQyYzcyNzQ3NDYzYTcxZDA4OTZiMjJmNmRhMycsXG4gICAgICAgICc1NTNlMDRmNmIwMThiNGZhNmM4ZjM5ZTdmMzExZDMxNzYyOTBkMGUwZjE5Y2E3M2YxNzcxNGQ5OTc3YTIyZmY4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzllMjE1OGYwZDdjMGQ1ZjI2YzM3OTFlZmVmYTc5NTk3NjU0ZTdhMmIyNDY0ZjUyYjFlZTZjMTM0Nzc2OWVmNTcnLFxuICAgICAgICAnNzEyZmNkZDFiOTA1M2YwOTAwM2EzNDgxZmE3NzYyZTlmZmQ3YzhlZjM1YTM4NTA5ZTJmYmYyNjI5MDA4MzczJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzE3NmUyNjk4OWE0M2M5Y2ZlYmE0MDI5YzIwMjUzOGMyODE3MmU1NjZlM2M0ZmNlNzMyMjg1N2YzYmUzMjdkNjYnLFxuICAgICAgICAnZWQ4Y2M5ZDA0YjI5ZWI4NzdkMjcwYjQ4NzhkYzQzYzE5YWVmZDMxZjRlZWUwOWVlN2I0NzgzNGMxZmE0YjFjMydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3NWQ0NmVmZWEzNzcxZTZlNjhhYmI4OWExM2FkNzQ3ZWNmMTg5MjM5M2RmYzRmMWI3MDA0Nzg4YzUwMzc0ZGE4JyxcbiAgICAgICAgJzk4NTIzOTBhOTk1MDc2NzlmZDBiODZmZDJiMzlhODY4ZDdlZmMyMjE1MTM0NmUxYTNjYTQ3MjY1ODZhNmJlZDgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnODA5YTIwYzY3ZDY0OTAwZmZiNjk4YzRjODI1ZjZkNWYyMzEwZmIwNDUxYzg2OTM0NWI3MzE5ZjY0NTYwNTcyMScsXG4gICAgICAgICc5ZTk5NDk4MGQ5OTE3ZTIyYjc2YjA2MTkyN2ZhMDQxNDNkMDk2Y2NjNTQ5NjNlNmE1ZWJmYTVmM2Y4ZTI4NmMxJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzFiMzg5MDNhNDNmN2YxMTRlZDQ1MDBiNGVhYzcwODNmZGVmZWNlMWNmMjljNjM1MjhkNTYzNDQ2Zjk3MmMxODAnLFxuICAgICAgICAnNDAzNmVkYzkzMWE2MGFlODg5MzUzZjc3ZmQ1M2RlNGEyNzA4YjI2YjZmNWRhNzJhZDMzOTQxMTlkYWY0MDhmOSdcbiAgICAgIF1cbiAgICBdXG4gIH1cbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IGV4cG9ydHM7XG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpO1xuXG51dGlscy5hc3NlcnQgPSBmdW5jdGlvbiBhc3NlcnQodmFsLCBtc2cpIHtcbiAgaWYgKCF2YWwpXG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZyB8fCAnQXNzZXJ0aW9uIGZhaWxlZCcpO1xufTtcblxuZnVuY3Rpb24gdG9BcnJheShtc2csIGVuYykge1xuICBpZiAoQXJyYXkuaXNBcnJheShtc2cpKVxuICAgIHJldHVybiBtc2cuc2xpY2UoKTtcbiAgaWYgKCFtc2cpXG4gICAgcmV0dXJuIFtdO1xuICB2YXIgcmVzID0gW107XG4gIGlmICh0eXBlb2YgbXNnICE9PSAnc3RyaW5nJykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKVxuICAgICAgcmVzW2ldID0gbXNnW2ldIHwgMDtcbiAgICByZXR1cm4gcmVzO1xuICB9XG4gIGlmICghZW5jKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBjID0gbXNnLmNoYXJDb2RlQXQoaSk7XG4gICAgICB2YXIgaGkgPSBjID4+IDg7XG4gICAgICB2YXIgbG8gPSBjICYgMHhmZjtcbiAgICAgIGlmIChoaSlcbiAgICAgICAgcmVzLnB1c2goaGksIGxvKTtcbiAgICAgIGVsc2VcbiAgICAgICAgcmVzLnB1c2gobG8pO1xuICAgIH1cbiAgfSBlbHNlIGlmIChlbmMgPT09ICdoZXgnKSB7XG4gICAgbXNnID0gbXNnLnJlcGxhY2UoL1teYS16MC05XSsvaWcsICcnKTtcbiAgICBpZiAobXNnLmxlbmd0aCAlIDIgIT09IDApXG4gICAgICBtc2cgPSAnMCcgKyBtc2c7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpICs9IDIpXG4gICAgICByZXMucHVzaChwYXJzZUludChtc2dbaV0gKyBtc2dbaSArIDFdLCAxNikpO1xuICB9XG4gIHJldHVybiByZXM7XG59XG51dGlscy50b0FycmF5ID0gdG9BcnJheTtcblxuZnVuY3Rpb24gemVybzIod29yZCkge1xuICBpZiAod29yZC5sZW5ndGggPT09IDEpXG4gICAgcmV0dXJuICcwJyArIHdvcmQ7XG4gIGVsc2VcbiAgICByZXR1cm4gd29yZDtcbn1cbnV0aWxzLnplcm8yID0gemVybzI7XG5cbmZ1bmN0aW9uIHRvSGV4KG1zZykge1xuICB2YXIgcmVzID0gJyc7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKVxuICAgIHJlcyArPSB6ZXJvMihtc2dbaV0udG9TdHJpbmcoMTYpKTtcbiAgcmV0dXJuIHJlcztcbn1cbnV0aWxzLnRvSGV4ID0gdG9IZXg7XG5cbnV0aWxzLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShhcnIsIGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdG9IZXgoYXJyKTtcbiAgZWxzZVxuICAgIHJldHVybiBhcnI7XG59O1xuXG4vLyBSZXByZXNlbnQgbnVtIGluIGEgdy1OQUYgZm9ybVxuZnVuY3Rpb24gZ2V0TkFGKG51bSwgdykge1xuICB2YXIgbmFmID0gW107XG4gIHZhciB3cyA9IDEgPDwgKHcgKyAxKTtcbiAgdmFyIGsgPSBudW0uY2xvbmUoKTtcbiAgd2hpbGUgKGsuY21wbigxKSA+PSAwKSB7XG4gICAgdmFyIHo7XG4gICAgaWYgKGsuaXNPZGQoKSkge1xuICAgICAgdmFyIG1vZCA9IGsuYW5kbG4od3MgLSAxKTtcbiAgICAgIGlmIChtb2QgPiAod3MgPj4gMSkgLSAxKVxuICAgICAgICB6ID0gKHdzID4+IDEpIC0gbW9kO1xuICAgICAgZWxzZVxuICAgICAgICB6ID0gbW9kO1xuICAgICAgay5pc3Vibih6KTtcbiAgICB9IGVsc2Uge1xuICAgICAgeiA9IDA7XG4gICAgfVxuICAgIG5hZi5wdXNoKHopO1xuXG4gICAgLy8gT3B0aW1pemF0aW9uLCBzaGlmdCBieSB3b3JkIGlmIHBvc3NpYmxlXG4gICAgdmFyIHNoaWZ0ID0gKGsuY21wbigwKSAhPT0gMCAmJiBrLmFuZGxuKHdzIC0gMSkgPT09IDApID8gKHcgKyAxKSA6IDE7XG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCBzaGlmdDsgaSsrKVxuICAgICAgbmFmLnB1c2goMCk7XG4gICAgay5pdXNocm4oc2hpZnQpO1xuICB9XG5cbiAgcmV0dXJuIG5hZjtcbn1cbnV0aWxzLmdldE5BRiA9IGdldE5BRjtcblxuLy8gUmVwcmVzZW50IGsxLCBrMiBpbiBhIEpvaW50IFNwYXJzZSBGb3JtXG5mdW5jdGlvbiBnZXRKU0YoazEsIGsyKSB7XG4gIHZhciBqc2YgPSBbXG4gICAgW10sXG4gICAgW11cbiAgXTtcblxuICBrMSA9IGsxLmNsb25lKCk7XG4gIGsyID0gazIuY2xvbmUoKTtcbiAgdmFyIGQxID0gMDtcbiAgdmFyIGQyID0gMDtcbiAgd2hpbGUgKGsxLmNtcG4oLWQxKSA+IDAgfHwgazIuY21wbigtZDIpID4gMCkge1xuXG4gICAgLy8gRmlyc3QgcGhhc2VcbiAgICB2YXIgbTE0ID0gKGsxLmFuZGxuKDMpICsgZDEpICYgMztcbiAgICB2YXIgbTI0ID0gKGsyLmFuZGxuKDMpICsgZDIpICYgMztcbiAgICBpZiAobTE0ID09PSAzKVxuICAgICAgbTE0ID0gLTE7XG4gICAgaWYgKG0yNCA9PT0gMylcbiAgICAgIG0yNCA9IC0xO1xuICAgIHZhciB1MTtcbiAgICBpZiAoKG0xNCAmIDEpID09PSAwKSB7XG4gICAgICB1MSA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBtOCA9IChrMS5hbmRsbig3KSArIGQxKSAmIDc7XG4gICAgICBpZiAoKG04ID09PSAzIHx8IG04ID09PSA1KSAmJiBtMjQgPT09IDIpXG4gICAgICAgIHUxID0gLW0xNDtcbiAgICAgIGVsc2VcbiAgICAgICAgdTEgPSBtMTQ7XG4gICAgfVxuICAgIGpzZlswXS5wdXNoKHUxKTtcblxuICAgIHZhciB1MjtcbiAgICBpZiAoKG0yNCAmIDEpID09PSAwKSB7XG4gICAgICB1MiA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBtOCA9IChrMi5hbmRsbig3KSArIGQyKSAmIDc7XG4gICAgICBpZiAoKG04ID09PSAzIHx8IG04ID09PSA1KSAmJiBtMTQgPT09IDIpXG4gICAgICAgIHUyID0gLW0yNDtcbiAgICAgIGVsc2VcbiAgICAgICAgdTIgPSBtMjQ7XG4gICAgfVxuICAgIGpzZlsxXS5wdXNoKHUyKTtcblxuICAgIC8vIFNlY29uZCBwaGFzZVxuICAgIGlmICgyICogZDEgPT09IHUxICsgMSlcbiAgICAgIGQxID0gMSAtIGQxO1xuICAgIGlmICgyICogZDIgPT09IHUyICsgMSlcbiAgICAgIGQyID0gMSAtIGQyO1xuICAgIGsxLml1c2hybigxKTtcbiAgICBrMi5pdXNocm4oMSk7XG4gIH1cblxuICByZXR1cm4ganNmO1xufVxudXRpbHMuZ2V0SlNGID0gZ2V0SlNGO1xuXG5mdW5jdGlvbiBjYWNoZWRQcm9wZXJ0eShvYmosIGNvbXB1dGVyKSB7XG4gIHZhciBuYW1lID0gY29tcHV0ZXIubmFtZTtcbiAgdmFyIGtleSA9ICdfJyArIG5hbWU7XG4gIG9iai5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbiBjYWNoZWRQcm9wZXJ0eSgpIHtcbiAgICByZXR1cm4gdGhpc1trZXldICE9PSB1bmRlZmluZWQgPyB0aGlzW2tleV0gOlxuICAgICAgICAgICB0aGlzW2tleV0gPSBjb21wdXRlci5jYWxsKHRoaXMpO1xuICB9O1xufVxudXRpbHMuY2FjaGVkUHJvcGVydHkgPSBjYWNoZWRQcm9wZXJ0eTtcblxuZnVuY3Rpb24gcGFyc2VCeXRlcyhieXRlcykge1xuICByZXR1cm4gdHlwZW9mIGJ5dGVzID09PSAnc3RyaW5nJyA/IHV0aWxzLnRvQXJyYXkoYnl0ZXMsICdoZXgnKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXM7XG59XG51dGlscy5wYXJzZUJ5dGVzID0gcGFyc2VCeXRlcztcblxuZnVuY3Rpb24gaW50RnJvbUxFKGJ5dGVzKSB7XG4gIHJldHVybiBuZXcgQk4oYnl0ZXMsICdoZXgnLCAnbGUnKTtcbn1cbnV0aWxzLmludEZyb21MRSA9IGludEZyb21MRTtcblxuIiwidmFyIHI7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcmFuZChsZW4pIHtcbiAgaWYgKCFyKVxuICAgIHIgPSBuZXcgUmFuZChudWxsKTtcblxuICByZXR1cm4gci5nZW5lcmF0ZShsZW4pO1xufTtcblxuZnVuY3Rpb24gUmFuZChyYW5kKSB7XG4gIHRoaXMucmFuZCA9IHJhbmQ7XG59XG5tb2R1bGUuZXhwb3J0cy5SYW5kID0gUmFuZDtcblxuUmFuZC5wcm90b3R5cGUuZ2VuZXJhdGUgPSBmdW5jdGlvbiBnZW5lcmF0ZShsZW4pIHtcbiAgcmV0dXJuIHRoaXMuX3JhbmQobGVuKTtcbn07XG5cbmlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0Jykge1xuICBpZiAod2luZG93LmNyeXB0byAmJiB3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcykge1xuICAgIC8vIE1vZGVybiBicm93c2Vyc1xuICAgIFJhbmQucHJvdG90eXBlLl9yYW5kID0gZnVuY3Rpb24gX3JhbmQobikge1xuICAgICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KG4pO1xuICAgICAgd2luZG93LmNyeXB0by5nZXRSYW5kb21WYWx1ZXMoYXJyKTtcbiAgICAgIHJldHVybiBhcnI7XG4gICAgfTtcbiAgfSBlbHNlIGlmICh3aW5kb3cubXNDcnlwdG8gJiYgd2luZG93Lm1zQ3J5cHRvLmdldFJhbmRvbVZhbHVlcykge1xuICAgIC8vIElFXG4gICAgUmFuZC5wcm90b3R5cGUuX3JhbmQgPSBmdW5jdGlvbiBfcmFuZChuKSB7XG4gICAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkobik7XG4gICAgICB3aW5kb3cubXNDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGFycik7XG4gICAgICByZXR1cm4gYXJyO1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgLy8gT2xkIGp1bmtcbiAgICBSYW5kLnByb3RvdHlwZS5fcmFuZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQgeWV0Jyk7XG4gICAgfTtcbiAgfVxufSBlbHNlIHtcbiAgLy8gTm9kZS5qcyBvciBXZWIgd29ya2VyXG4gIHRyeSB7XG4gICAgdmFyIGNyeXB0byA9IHJlcXVpcmUoJ2NyeScgKyAncHRvJyk7XG5cbiAgICBSYW5kLnByb3RvdHlwZS5fcmFuZCA9IGZ1bmN0aW9uIF9yYW5kKG4pIHtcbiAgICAgIHJldHVybiBjcnlwdG8ucmFuZG9tQnl0ZXMobik7XG4gICAgfTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIEVtdWxhdGUgY3J5cHRvIEFQSSB1c2luZyByYW5keVxuICAgIFJhbmQucHJvdG90eXBlLl9yYW5kID0gZnVuY3Rpb24gX3JhbmQobikge1xuICAgICAgdmFyIHJlcyA9IG5ldyBVaW50OEFycmF5KG4pO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXMubGVuZ3RoOyBpKyspXG4gICAgICAgIHJlc1tpXSA9IHRoaXMucmFuZC5nZXRCeXRlKCk7XG4gICAgICByZXR1cm4gcmVzO1xuICAgIH07XG4gIH1cbn1cbiIsInZhciBoYXNoID0gZXhwb3J0cztcblxuaGFzaC51dGlscyA9IHJlcXVpcmUoJy4vaGFzaC91dGlscycpO1xuaGFzaC5jb21tb24gPSByZXF1aXJlKCcuL2hhc2gvY29tbW9uJyk7XG5oYXNoLnNoYSA9IHJlcXVpcmUoJy4vaGFzaC9zaGEnKTtcbmhhc2gucmlwZW1kID0gcmVxdWlyZSgnLi9oYXNoL3JpcGVtZCcpO1xuaGFzaC5obWFjID0gcmVxdWlyZSgnLi9oYXNoL2htYWMnKTtcblxuLy8gUHJveHkgaGFzaCBmdW5jdGlvbnMgdG8gdGhlIG1haW4gb2JqZWN0XG5oYXNoLnNoYTEgPSBoYXNoLnNoYS5zaGExO1xuaGFzaC5zaGEyNTYgPSBoYXNoLnNoYS5zaGEyNTY7XG5oYXNoLnNoYTIyNCA9IGhhc2guc2hhLnNoYTIyNDtcbmhhc2guc2hhMzg0ID0gaGFzaC5zaGEuc2hhMzg0O1xuaGFzaC5zaGE1MTIgPSBoYXNoLnNoYS5zaGE1MTI7XG5oYXNoLnJpcGVtZDE2MCA9IGhhc2gucmlwZW1kLnJpcGVtZDE2MDtcbiIsInZhciBoYXNoID0gcmVxdWlyZSgnLi4vaGFzaCcpO1xudmFyIHV0aWxzID0gaGFzaC51dGlscztcbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG5cbmZ1bmN0aW9uIEJsb2NrSGFzaCgpIHtcbiAgdGhpcy5wZW5kaW5nID0gbnVsbDtcbiAgdGhpcy5wZW5kaW5nVG90YWwgPSAwO1xuICB0aGlzLmJsb2NrU2l6ZSA9IHRoaXMuY29uc3RydWN0b3IuYmxvY2tTaXplO1xuICB0aGlzLm91dFNpemUgPSB0aGlzLmNvbnN0cnVjdG9yLm91dFNpemU7XG4gIHRoaXMuaG1hY1N0cmVuZ3RoID0gdGhpcy5jb25zdHJ1Y3Rvci5obWFjU3RyZW5ndGg7XG4gIHRoaXMucGFkTGVuZ3RoID0gdGhpcy5jb25zdHJ1Y3Rvci5wYWRMZW5ndGggLyA4O1xuICB0aGlzLmVuZGlhbiA9ICdiaWcnO1xuXG4gIHRoaXMuX2RlbHRhOCA9IHRoaXMuYmxvY2tTaXplIC8gODtcbiAgdGhpcy5fZGVsdGEzMiA9IHRoaXMuYmxvY2tTaXplIC8gMzI7XG59XG5leHBvcnRzLkJsb2NrSGFzaCA9IEJsb2NrSGFzaDtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUobXNnLCBlbmMpIHtcbiAgLy8gQ29udmVydCBtZXNzYWdlIHRvIGFycmF5LCBwYWQgaXQsIGFuZCBqb2luIGludG8gMzJiaXQgYmxvY2tzXG4gIG1zZyA9IHV0aWxzLnRvQXJyYXkobXNnLCBlbmMpO1xuICBpZiAoIXRoaXMucGVuZGluZylcbiAgICB0aGlzLnBlbmRpbmcgPSBtc2c7XG4gIGVsc2VcbiAgICB0aGlzLnBlbmRpbmcgPSB0aGlzLnBlbmRpbmcuY29uY2F0KG1zZyk7XG4gIHRoaXMucGVuZGluZ1RvdGFsICs9IG1zZy5sZW5ndGg7XG5cbiAgLy8gRW5vdWdoIGRhdGEsIHRyeSB1cGRhdGluZ1xuICBpZiAodGhpcy5wZW5kaW5nLmxlbmd0aCA+PSB0aGlzLl9kZWx0YTgpIHtcbiAgICBtc2cgPSB0aGlzLnBlbmRpbmc7XG5cbiAgICAvLyBQcm9jZXNzIHBlbmRpbmcgZGF0YSBpbiBibG9ja3NcbiAgICB2YXIgciA9IG1zZy5sZW5ndGggJSB0aGlzLl9kZWx0YTg7XG4gICAgdGhpcy5wZW5kaW5nID0gbXNnLnNsaWNlKG1zZy5sZW5ndGggLSByLCBtc2cubGVuZ3RoKTtcbiAgICBpZiAodGhpcy5wZW5kaW5nLmxlbmd0aCA9PT0gMClcbiAgICAgIHRoaXMucGVuZGluZyA9IG51bGw7XG5cbiAgICBtc2cgPSB1dGlscy5qb2luMzIobXNnLCAwLCBtc2cubGVuZ3RoIC0gciwgdGhpcy5lbmRpYW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSArPSB0aGlzLl9kZWx0YTMyKVxuICAgICAgdGhpcy5fdXBkYXRlKG1zZywgaSwgaSArIHRoaXMuX2RlbHRhMzIpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5CbG9ja0hhc2gucHJvdG90eXBlLmRpZ2VzdCA9IGZ1bmN0aW9uIGRpZ2VzdChlbmMpIHtcbiAgdGhpcy51cGRhdGUodGhpcy5fcGFkKCkpO1xuICBhc3NlcnQodGhpcy5wZW5kaW5nID09PSBudWxsKTtcblxuICByZXR1cm4gdGhpcy5fZGlnZXN0KGVuYyk7XG59O1xuXG5CbG9ja0hhc2gucHJvdG90eXBlLl9wYWQgPSBmdW5jdGlvbiBwYWQoKSB7XG4gIHZhciBsZW4gPSB0aGlzLnBlbmRpbmdUb3RhbDtcbiAgdmFyIGJ5dGVzID0gdGhpcy5fZGVsdGE4O1xuICB2YXIgayA9IGJ5dGVzIC0gKChsZW4gKyB0aGlzLnBhZExlbmd0aCkgJSBieXRlcyk7XG4gIHZhciByZXMgPSBuZXcgQXJyYXkoayArIHRoaXMucGFkTGVuZ3RoKTtcbiAgcmVzWzBdID0gMHg4MDtcbiAgZm9yICh2YXIgaSA9IDE7IGkgPCBrOyBpKyspXG4gICAgcmVzW2ldID0gMDtcblxuICAvLyBBcHBlbmQgbGVuZ3RoXG4gIGxlbiA8PD0gMztcbiAgaWYgKHRoaXMuZW5kaWFuID09PSAnYmlnJykge1xuICAgIGZvciAodmFyIHQgPSA4OyB0IDwgdGhpcy5wYWRMZW5ndGg7IHQrKylcbiAgICAgIHJlc1tpKytdID0gMDtcblxuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDI0KSAmIDB4ZmY7XG4gICAgcmVzW2krK10gPSAobGVuID4+PiAxNikgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gOCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gbGVuICYgMHhmZjtcbiAgfSBlbHNlIHtcbiAgICByZXNbaSsrXSA9IGxlbiAmIDB4ZmY7XG4gICAgcmVzW2krK10gPSAobGVuID4+PiA4KSAmIDB4ZmY7XG4gICAgcmVzW2krK10gPSAobGVuID4+PiAxNikgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMjQpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG5cbiAgICBmb3IgKHZhciB0ID0gODsgdCA8IHRoaXMucGFkTGVuZ3RoOyB0KyspXG4gICAgICByZXNbaSsrXSA9IDA7XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcbiIsInZhciBobWFjID0gZXhwb3J0cztcblxudmFyIGhhc2ggPSByZXF1aXJlKCcuLi9oYXNoJyk7XG52YXIgdXRpbHMgPSBoYXNoLnV0aWxzO1xudmFyIGFzc2VydCA9IHV0aWxzLmFzc2VydDtcblxuZnVuY3Rpb24gSG1hYyhoYXNoLCBrZXksIGVuYykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgSG1hYykpXG4gICAgcmV0dXJuIG5ldyBIbWFjKGhhc2gsIGtleSwgZW5jKTtcbiAgdGhpcy5IYXNoID0gaGFzaDtcbiAgdGhpcy5ibG9ja1NpemUgPSBoYXNoLmJsb2NrU2l6ZSAvIDg7XG4gIHRoaXMub3V0U2l6ZSA9IGhhc2gub3V0U2l6ZSAvIDg7XG4gIHRoaXMuaW5uZXIgPSBudWxsO1xuICB0aGlzLm91dGVyID0gbnVsbDtcblxuICB0aGlzLl9pbml0KHV0aWxzLnRvQXJyYXkoa2V5LCBlbmMpKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gSG1hYztcblxuSG1hYy5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiBpbml0KGtleSkge1xuICAvLyBTaG9ydGVuIGtleSwgaWYgbmVlZGVkXG4gIGlmIChrZXkubGVuZ3RoID4gdGhpcy5ibG9ja1NpemUpXG4gICAga2V5ID0gbmV3IHRoaXMuSGFzaCgpLnVwZGF0ZShrZXkpLmRpZ2VzdCgpO1xuICBhc3NlcnQoa2V5Lmxlbmd0aCA8PSB0aGlzLmJsb2NrU2l6ZSk7XG5cbiAgLy8gQWRkIHBhZGRpbmcgdG8ga2V5XG4gIGZvciAodmFyIGkgPSBrZXkubGVuZ3RoOyBpIDwgdGhpcy5ibG9ja1NpemU7IGkrKylcbiAgICBrZXkucHVzaCgwKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGtleS5sZW5ndGg7IGkrKylcbiAgICBrZXlbaV0gXj0gMHgzNjtcbiAgdGhpcy5pbm5lciA9IG5ldyB0aGlzLkhhc2goKS51cGRhdGUoa2V5KTtcblxuICAvLyAweDM2IF4gMHg1YyA9IDB4NmFcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXkubGVuZ3RoOyBpKyspXG4gICAga2V5W2ldIF49IDB4NmE7XG4gIHRoaXMub3V0ZXIgPSBuZXcgdGhpcy5IYXNoKCkudXBkYXRlKGtleSk7XG59O1xuXG5IbWFjLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUobXNnLCBlbmMpIHtcbiAgdGhpcy5pbm5lci51cGRhdGUobXNnLCBlbmMpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkhtYWMucHJvdG90eXBlLmRpZ2VzdCA9IGZ1bmN0aW9uIGRpZ2VzdChlbmMpIHtcbiAgdGhpcy5vdXRlci51cGRhdGUodGhpcy5pbm5lci5kaWdlc3QoKSk7XG4gIHJldHVybiB0aGlzLm91dGVyLmRpZ2VzdChlbmMpO1xufTtcbiIsInZhciBoYXNoID0gcmVxdWlyZSgnLi4vaGFzaCcpO1xudmFyIHV0aWxzID0gaGFzaC51dGlscztcblxudmFyIHJvdGwzMiA9IHV0aWxzLnJvdGwzMjtcbnZhciBzdW0zMiA9IHV0aWxzLnN1bTMyO1xudmFyIHN1bTMyXzMgPSB1dGlscy5zdW0zMl8zO1xudmFyIHN1bTMyXzQgPSB1dGlscy5zdW0zMl80O1xudmFyIEJsb2NrSGFzaCA9IGhhc2guY29tbW9uLkJsb2NrSGFzaDtcblxuZnVuY3Rpb24gUklQRU1EMTYwKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUklQRU1EMTYwKSlcbiAgICByZXR1cm4gbmV3IFJJUEVNRDE2MCgpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuXG4gIHRoaXMuaCA9IFsgMHg2NzQ1MjMwMSwgMHhlZmNkYWI4OSwgMHg5OGJhZGNmZSwgMHgxMDMyNTQ3NiwgMHhjM2QyZTFmMCBdO1xuICB0aGlzLmVuZGlhbiA9ICdsaXR0bGUnO1xufVxudXRpbHMuaW5oZXJpdHMoUklQRU1EMTYwLCBCbG9ja0hhc2gpO1xuZXhwb3J0cy5yaXBlbWQxNjAgPSBSSVBFTUQxNjA7XG5cblJJUEVNRDE2MC5ibG9ja1NpemUgPSA1MTI7XG5SSVBFTUQxNjAub3V0U2l6ZSA9IDE2MDtcblJJUEVNRDE2MC5obWFjU3RyZW5ndGggPSAxOTI7XG5SSVBFTUQxNjAucGFkTGVuZ3RoID0gNjQ7XG5cblJJUEVNRDE2MC5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIHVwZGF0ZShtc2csIHN0YXJ0KSB7XG4gIHZhciBBID0gdGhpcy5oWzBdO1xuICB2YXIgQiA9IHRoaXMuaFsxXTtcbiAgdmFyIEMgPSB0aGlzLmhbMl07XG4gIHZhciBEID0gdGhpcy5oWzNdO1xuICB2YXIgRSA9IHRoaXMuaFs0XTtcbiAgdmFyIEFoID0gQTtcbiAgdmFyIEJoID0gQjtcbiAgdmFyIENoID0gQztcbiAgdmFyIERoID0gRDtcbiAgdmFyIEVoID0gRTtcbiAgZm9yICh2YXIgaiA9IDA7IGogPCA4MDsgaisrKSB7XG4gICAgdmFyIFQgPSBzdW0zMihcbiAgICAgIHJvdGwzMihcbiAgICAgICAgc3VtMzJfNChBLCBmKGosIEIsIEMsIEQpLCBtc2dbcltqXSArIHN0YXJ0XSwgSyhqKSksXG4gICAgICAgIHNbal0pLFxuICAgICAgRSk7XG4gICAgQSA9IEU7XG4gICAgRSA9IEQ7XG4gICAgRCA9IHJvdGwzMihDLCAxMCk7XG4gICAgQyA9IEI7XG4gICAgQiA9IFQ7XG4gICAgVCA9IHN1bTMyKFxuICAgICAgcm90bDMyKFxuICAgICAgICBzdW0zMl80KEFoLCBmKDc5IC0gaiwgQmgsIENoLCBEaCksIG1zZ1tyaFtqXSArIHN0YXJ0XSwgS2goaikpLFxuICAgICAgICBzaFtqXSksXG4gICAgICBFaCk7XG4gICAgQWggPSBFaDtcbiAgICBFaCA9IERoO1xuICAgIERoID0gcm90bDMyKENoLCAxMCk7XG4gICAgQ2ggPSBCaDtcbiAgICBCaCA9IFQ7XG4gIH1cbiAgVCA9IHN1bTMyXzModGhpcy5oWzFdLCBDLCBEaCk7XG4gIHRoaXMuaFsxXSA9IHN1bTMyXzModGhpcy5oWzJdLCBELCBFaCk7XG4gIHRoaXMuaFsyXSA9IHN1bTMyXzModGhpcy5oWzNdLCBFLCBBaCk7XG4gIHRoaXMuaFszXSA9IHN1bTMyXzModGhpcy5oWzRdLCBBLCBCaCk7XG4gIHRoaXMuaFs0XSA9IHN1bTMyXzModGhpcy5oWzBdLCBCLCBDaCk7XG4gIHRoaXMuaFswXSA9IFQ7XG59O1xuXG5SSVBFTUQxNjAucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaCwgJ2xpdHRsZScpO1xuICBlbHNlXG4gICAgcmV0dXJuIHV0aWxzLnNwbGl0MzIodGhpcy5oLCAnbGl0dGxlJyk7XG59O1xuXG5mdW5jdGlvbiBmKGosIHgsIHksIHopIHtcbiAgaWYgKGogPD0gMTUpXG4gICAgcmV0dXJuIHggXiB5IF4gejtcbiAgZWxzZSBpZiAoaiA8PSAzMSlcbiAgICByZXR1cm4gKHggJiB5KSB8ICgofngpICYgeik7XG4gIGVsc2UgaWYgKGogPD0gNDcpXG4gICAgcmV0dXJuICh4IHwgKH55KSkgXiB6O1xuICBlbHNlIGlmIChqIDw9IDYzKVxuICAgIHJldHVybiAoeCAmIHopIHwgKHkgJiAofnopKTtcbiAgZWxzZVxuICAgIHJldHVybiB4IF4gKHkgfCAofnopKTtcbn1cblxuZnVuY3Rpb24gSyhqKSB7XG4gIGlmIChqIDw9IDE1KVxuICAgIHJldHVybiAweDAwMDAwMDAwO1xuICBlbHNlIGlmIChqIDw9IDMxKVxuICAgIHJldHVybiAweDVhODI3OTk5O1xuICBlbHNlIGlmIChqIDw9IDQ3KVxuICAgIHJldHVybiAweDZlZDllYmExO1xuICBlbHNlIGlmIChqIDw9IDYzKVxuICAgIHJldHVybiAweDhmMWJiY2RjO1xuICBlbHNlXG4gICAgcmV0dXJuIDB4YTk1M2ZkNGU7XG59XG5cbmZ1bmN0aW9uIEtoKGopIHtcbiAgaWYgKGogPD0gMTUpXG4gICAgcmV0dXJuIDB4NTBhMjhiZTY7XG4gIGVsc2UgaWYgKGogPD0gMzEpXG4gICAgcmV0dXJuIDB4NWM0ZGQxMjQ7XG4gIGVsc2UgaWYgKGogPD0gNDcpXG4gICAgcmV0dXJuIDB4NmQ3MDNlZjM7XG4gIGVsc2UgaWYgKGogPD0gNjMpXG4gICAgcmV0dXJuIDB4N2E2ZDc2ZTk7XG4gIGVsc2VcbiAgICByZXR1cm4gMHgwMDAwMDAwMDtcbn1cblxudmFyIHIgPSBbXG4gIDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsXG4gIDcsIDQsIDEzLCAxLCAxMCwgNiwgMTUsIDMsIDEyLCAwLCA5LCA1LCAyLCAxNCwgMTEsIDgsXG4gIDMsIDEwLCAxNCwgNCwgOSwgMTUsIDgsIDEsIDIsIDcsIDAsIDYsIDEzLCAxMSwgNSwgMTIsXG4gIDEsIDksIDExLCAxMCwgMCwgOCwgMTIsIDQsIDEzLCAzLCA3LCAxNSwgMTQsIDUsIDYsIDIsXG4gIDQsIDAsIDUsIDksIDcsIDEyLCAyLCAxMCwgMTQsIDEsIDMsIDgsIDExLCA2LCAxNSwgMTNcbl07XG5cbnZhciByaCA9IFtcbiAgNSwgMTQsIDcsIDAsIDksIDIsIDExLCA0LCAxMywgNiwgMTUsIDgsIDEsIDEwLCAzLCAxMixcbiAgNiwgMTEsIDMsIDcsIDAsIDEzLCA1LCAxMCwgMTQsIDE1LCA4LCAxMiwgNCwgOSwgMSwgMixcbiAgMTUsIDUsIDEsIDMsIDcsIDE0LCA2LCA5LCAxMSwgOCwgMTIsIDIsIDEwLCAwLCA0LCAxMyxcbiAgOCwgNiwgNCwgMSwgMywgMTEsIDE1LCAwLCA1LCAxMiwgMiwgMTMsIDksIDcsIDEwLCAxNCxcbiAgMTIsIDE1LCAxMCwgNCwgMSwgNSwgOCwgNywgNiwgMiwgMTMsIDE0LCAwLCAzLCA5LCAxMVxuXTtcblxudmFyIHMgPSBbXG4gIDExLCAxNCwgMTUsIDEyLCA1LCA4LCA3LCA5LCAxMSwgMTMsIDE0LCAxNSwgNiwgNywgOSwgOCxcbiAgNywgNiwgOCwgMTMsIDExLCA5LCA3LCAxNSwgNywgMTIsIDE1LCA5LCAxMSwgNywgMTMsIDEyLFxuICAxMSwgMTMsIDYsIDcsIDE0LCA5LCAxMywgMTUsIDE0LCA4LCAxMywgNiwgNSwgMTIsIDcsIDUsXG4gIDExLCAxMiwgMTQsIDE1LCAxNCwgMTUsIDksIDgsIDksIDE0LCA1LCA2LCA4LCA2LCA1LCAxMixcbiAgOSwgMTUsIDUsIDExLCA2LCA4LCAxMywgMTIsIDUsIDEyLCAxMywgMTQsIDExLCA4LCA1LCA2XG5dO1xuXG52YXIgc2ggPSBbXG4gIDgsIDksIDksIDExLCAxMywgMTUsIDE1LCA1LCA3LCA3LCA4LCAxMSwgMTQsIDE0LCAxMiwgNixcbiAgOSwgMTMsIDE1LCA3LCAxMiwgOCwgOSwgMTEsIDcsIDcsIDEyLCA3LCA2LCAxNSwgMTMsIDExLFxuICA5LCA3LCAxNSwgMTEsIDgsIDYsIDYsIDE0LCAxMiwgMTMsIDUsIDE0LCAxMywgMTMsIDcsIDUsXG4gIDE1LCA1LCA4LCAxMSwgMTQsIDE0LCA2LCAxNCwgNiwgOSwgMTIsIDksIDEyLCA1LCAxNSwgOCxcbiAgOCwgNSwgMTIsIDksIDEyLCA1LCAxNCwgNiwgOCwgMTMsIDYsIDUsIDE1LCAxMywgMTEsIDExXG5dO1xuIiwidmFyIGhhc2ggPSByZXF1aXJlKCcuLi9oYXNoJyk7XG52YXIgdXRpbHMgPSBoYXNoLnV0aWxzO1xudmFyIGFzc2VydCA9IHV0aWxzLmFzc2VydDtcblxudmFyIHJvdHIzMiA9IHV0aWxzLnJvdHIzMjtcbnZhciByb3RsMzIgPSB1dGlscy5yb3RsMzI7XG52YXIgc3VtMzIgPSB1dGlscy5zdW0zMjtcbnZhciBzdW0zMl80ID0gdXRpbHMuc3VtMzJfNDtcbnZhciBzdW0zMl81ID0gdXRpbHMuc3VtMzJfNTtcbnZhciByb3RyNjRfaGkgPSB1dGlscy5yb3RyNjRfaGk7XG52YXIgcm90cjY0X2xvID0gdXRpbHMucm90cjY0X2xvO1xudmFyIHNocjY0X2hpID0gdXRpbHMuc2hyNjRfaGk7XG52YXIgc2hyNjRfbG8gPSB1dGlscy5zaHI2NF9sbztcbnZhciBzdW02NCA9IHV0aWxzLnN1bTY0O1xudmFyIHN1bTY0X2hpID0gdXRpbHMuc3VtNjRfaGk7XG52YXIgc3VtNjRfbG8gPSB1dGlscy5zdW02NF9sbztcbnZhciBzdW02NF80X2hpID0gdXRpbHMuc3VtNjRfNF9oaTtcbnZhciBzdW02NF80X2xvID0gdXRpbHMuc3VtNjRfNF9sbztcbnZhciBzdW02NF81X2hpID0gdXRpbHMuc3VtNjRfNV9oaTtcbnZhciBzdW02NF81X2xvID0gdXRpbHMuc3VtNjRfNV9sbztcbnZhciBCbG9ja0hhc2ggPSBoYXNoLmNvbW1vbi5CbG9ja0hhc2g7XG5cbnZhciBzaGEyNTZfSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHg3MTM3NDQ5MSwgMHhiNWMwZmJjZiwgMHhlOWI1ZGJhNSxcbiAgMHgzOTU2YzI1YiwgMHg1OWYxMTFmMSwgMHg5MjNmODJhNCwgMHhhYjFjNWVkNSxcbiAgMHhkODA3YWE5OCwgMHgxMjgzNWIwMSwgMHgyNDMxODViZSwgMHg1NTBjN2RjMyxcbiAgMHg3MmJlNWQ3NCwgMHg4MGRlYjFmZSwgMHg5YmRjMDZhNywgMHhjMTliZjE3NCxcbiAgMHhlNDliNjljMSwgMHhlZmJlNDc4NiwgMHgwZmMxOWRjNiwgMHgyNDBjYTFjYyxcbiAgMHgyZGU5MmM2ZiwgMHg0YTc0ODRhYSwgMHg1Y2IwYTlkYywgMHg3NmY5ODhkYSxcbiAgMHg5ODNlNTE1MiwgMHhhODMxYzY2ZCwgMHhiMDAzMjdjOCwgMHhiZjU5N2ZjNyxcbiAgMHhjNmUwMGJmMywgMHhkNWE3OTE0NywgMHgwNmNhNjM1MSwgMHgxNDI5Mjk2NyxcbiAgMHgyN2I3MGE4NSwgMHgyZTFiMjEzOCwgMHg0ZDJjNmRmYywgMHg1MzM4MGQxMyxcbiAgMHg2NTBhNzM1NCwgMHg3NjZhMGFiYiwgMHg4MWMyYzkyZSwgMHg5MjcyMmM4NSxcbiAgMHhhMmJmZThhMSwgMHhhODFhNjY0YiwgMHhjMjRiOGI3MCwgMHhjNzZjNTFhMyxcbiAgMHhkMTkyZTgxOSwgMHhkNjk5MDYyNCwgMHhmNDBlMzU4NSwgMHgxMDZhYTA3MCxcbiAgMHgxOWE0YzExNiwgMHgxZTM3NmMwOCwgMHgyNzQ4Nzc0YywgMHgzNGIwYmNiNSxcbiAgMHgzOTFjMGNiMywgMHg0ZWQ4YWE0YSwgMHg1YjljY2E0ZiwgMHg2ODJlNmZmMyxcbiAgMHg3NDhmODJlZSwgMHg3OGE1NjM2ZiwgMHg4NGM4NzgxNCwgMHg4Y2M3MDIwOCxcbiAgMHg5MGJlZmZmYSwgMHhhNDUwNmNlYiwgMHhiZWY5YTNmNywgMHhjNjcxNzhmMlxuXTtcblxudmFyIHNoYTUxMl9LID0gW1xuICAweDQyOGEyZjk4LCAweGQ3MjhhZTIyLCAweDcxMzc0NDkxLCAweDIzZWY2NWNkLFxuICAweGI1YzBmYmNmLCAweGVjNGQzYjJmLCAweGU5YjVkYmE1LCAweDgxODlkYmJjLFxuICAweDM5NTZjMjViLCAweGYzNDhiNTM4LCAweDU5ZjExMWYxLCAweGI2MDVkMDE5LFxuICAweDkyM2Y4MmE0LCAweGFmMTk0ZjliLCAweGFiMWM1ZWQ1LCAweGRhNmQ4MTE4LFxuICAweGQ4MDdhYTk4LCAweGEzMDMwMjQyLCAweDEyODM1YjAxLCAweDQ1NzA2ZmJlLFxuICAweDI0MzE4NWJlLCAweDRlZTRiMjhjLCAweDU1MGM3ZGMzLCAweGQ1ZmZiNGUyLFxuICAweDcyYmU1ZDc0LCAweGYyN2I4OTZmLCAweDgwZGViMWZlLCAweDNiMTY5NmIxLFxuICAweDliZGMwNmE3LCAweDI1YzcxMjM1LCAweGMxOWJmMTc0LCAweGNmNjkyNjk0LFxuICAweGU0OWI2OWMxLCAweDllZjE0YWQyLCAweGVmYmU0Nzg2LCAweDM4NGYyNWUzLFxuICAweDBmYzE5ZGM2LCAweDhiOGNkNWI1LCAweDI0MGNhMWNjLCAweDc3YWM5YzY1LFxuICAweDJkZTkyYzZmLCAweDU5MmIwMjc1LCAweDRhNzQ4NGFhLCAweDZlYTZlNDgzLFxuICAweDVjYjBhOWRjLCAweGJkNDFmYmQ0LCAweDc2Zjk4OGRhLCAweDgzMTE1M2I1LFxuICAweDk4M2U1MTUyLCAweGVlNjZkZmFiLCAweGE4MzFjNjZkLCAweDJkYjQzMjEwLFxuICAweGIwMDMyN2M4LCAweDk4ZmIyMTNmLCAweGJmNTk3ZmM3LCAweGJlZWYwZWU0LFxuICAweGM2ZTAwYmYzLCAweDNkYTg4ZmMyLCAweGQ1YTc5MTQ3LCAweDkzMGFhNzI1LFxuICAweDA2Y2E2MzUxLCAweGUwMDM4MjZmLCAweDE0MjkyOTY3LCAweDBhMGU2ZTcwLFxuICAweDI3YjcwYTg1LCAweDQ2ZDIyZmZjLCAweDJlMWIyMTM4LCAweDVjMjZjOTI2LFxuICAweDRkMmM2ZGZjLCAweDVhYzQyYWVkLCAweDUzMzgwZDEzLCAweDlkOTViM2RmLFxuICAweDY1MGE3MzU0LCAweDhiYWY2M2RlLCAweDc2NmEwYWJiLCAweDNjNzdiMmE4LFxuICAweDgxYzJjOTJlLCAweDQ3ZWRhZWU2LCAweDkyNzIyYzg1LCAweDE0ODIzNTNiLFxuICAweGEyYmZlOGExLCAweDRjZjEwMzY0LCAweGE4MWE2NjRiLCAweGJjNDIzMDAxLFxuICAweGMyNGI4YjcwLCAweGQwZjg5NzkxLCAweGM3NmM1MWEzLCAweDA2NTRiZTMwLFxuICAweGQxOTJlODE5LCAweGQ2ZWY1MjE4LCAweGQ2OTkwNjI0LCAweDU1NjVhOTEwLFxuICAweGY0MGUzNTg1LCAweDU3NzEyMDJhLCAweDEwNmFhMDcwLCAweDMyYmJkMWI4LFxuICAweDE5YTRjMTE2LCAweGI4ZDJkMGM4LCAweDFlMzc2YzA4LCAweDUxNDFhYjUzLFxuICAweDI3NDg3NzRjLCAweGRmOGVlYjk5LCAweDM0YjBiY2I1LCAweGUxOWI0OGE4LFxuICAweDM5MWMwY2IzLCAweGM1Yzk1YTYzLCAweDRlZDhhYTRhLCAweGUzNDE4YWNiLFxuICAweDViOWNjYTRmLCAweDc3NjNlMzczLCAweDY4MmU2ZmYzLCAweGQ2YjJiOGEzLFxuICAweDc0OGY4MmVlLCAweDVkZWZiMmZjLCAweDc4YTU2MzZmLCAweDQzMTcyZjYwLFxuICAweDg0Yzg3ODE0LCAweGExZjBhYjcyLCAweDhjYzcwMjA4LCAweDFhNjQzOWVjLFxuICAweDkwYmVmZmZhLCAweDIzNjMxZTI4LCAweGE0NTA2Y2ViLCAweGRlODJiZGU5LFxuICAweGJlZjlhM2Y3LCAweGIyYzY3OTE1LCAweGM2NzE3OGYyLCAweGUzNzI1MzJiLFxuICAweGNhMjczZWNlLCAweGVhMjY2MTljLCAweGQxODZiOGM3LCAweDIxYzBjMjA3LFxuICAweGVhZGE3ZGQ2LCAweGNkZTBlYjFlLCAweGY1N2Q0ZjdmLCAweGVlNmVkMTc4LFxuICAweDA2ZjA2N2FhLCAweDcyMTc2ZmJhLCAweDBhNjM3ZGM1LCAweGEyYzg5OGE2LFxuICAweDExM2Y5ODA0LCAweGJlZjkwZGFlLCAweDFiNzEwYjM1LCAweDEzMWM0NzFiLFxuICAweDI4ZGI3N2Y1LCAweDIzMDQ3ZDg0LCAweDMyY2FhYjdiLCAweDQwYzcyNDkzLFxuICAweDNjOWViZTBhLCAweDE1YzliZWJjLCAweDQzMWQ2N2M0LCAweDljMTAwZDRjLFxuICAweDRjYzVkNGJlLCAweGNiM2U0MmI2LCAweDU5N2YyOTljLCAweGZjNjU3ZTJhLFxuICAweDVmY2I2ZmFiLCAweDNhZDZmYWVjLCAweDZjNDQxOThjLCAweDRhNDc1ODE3XG5dO1xuXG52YXIgc2hhMV9LID0gW1xuICAweDVBODI3OTk5LCAweDZFRDlFQkExLFxuICAweDhGMUJCQ0RDLCAweENBNjJDMUQ2XG5dO1xuXG5mdW5jdGlvbiBTSEEyNTYoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTSEEyNTYpKVxuICAgIHJldHVybiBuZXcgU0hBMjU2KCk7XG5cbiAgQmxvY2tIYXNoLmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFsgMHg2YTA5ZTY2NywgMHhiYjY3YWU4NSwgMHgzYzZlZjM3MiwgMHhhNTRmZjUzYSxcbiAgICAgICAgICAgICAweDUxMGU1MjdmLCAweDliMDU2ODhjLCAweDFmODNkOWFiLCAweDViZTBjZDE5IF07XG4gIHRoaXMuayA9IHNoYTI1Nl9LO1xuICB0aGlzLlcgPSBuZXcgQXJyYXkoNjQpO1xufVxudXRpbHMuaW5oZXJpdHMoU0hBMjU2LCBCbG9ja0hhc2gpO1xuZXhwb3J0cy5zaGEyNTYgPSBTSEEyNTY7XG5cblNIQTI1Ni5ibG9ja1NpemUgPSA1MTI7XG5TSEEyNTYub3V0U2l6ZSA9IDI1NjtcblNIQTI1Ni5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEEyNTYucGFkTGVuZ3RoID0gNjQ7XG5cblNIQTI1Ni5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuICBmb3IgKDsgaSA8IFcubGVuZ3RoOyBpKyspXG4gICAgV1tpXSA9IHN1bTMyXzQoZzFfMjU2KFdbaSAtIDJdKSwgV1tpIC0gN10sIGcwXzI1NihXW2kgLSAxNV0pLCBXW2kgLSAxNl0pO1xuXG4gIHZhciBhID0gdGhpcy5oWzBdO1xuICB2YXIgYiA9IHRoaXMuaFsxXTtcbiAgdmFyIGMgPSB0aGlzLmhbMl07XG4gIHZhciBkID0gdGhpcy5oWzNdO1xuICB2YXIgZSA9IHRoaXMuaFs0XTtcbiAgdmFyIGYgPSB0aGlzLmhbNV07XG4gIHZhciBnID0gdGhpcy5oWzZdO1xuICB2YXIgaCA9IHRoaXMuaFs3XTtcblxuICBhc3NlcnQodGhpcy5rLmxlbmd0aCA9PT0gVy5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IFcubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgVDEgPSBzdW0zMl81KGgsIHMxXzI1NihlKSwgY2gzMihlLCBmLCBnKSwgdGhpcy5rW2ldLCBXW2ldKTtcbiAgICB2YXIgVDIgPSBzdW0zMihzMF8yNTYoYSksIG1hajMyKGEsIGIsIGMpKTtcbiAgICBoID0gZztcbiAgICBnID0gZjtcbiAgICBmID0gZTtcbiAgICBlID0gc3VtMzIoZCwgVDEpO1xuICAgIGQgPSBjO1xuICAgIGMgPSBiO1xuICAgIGIgPSBhO1xuICAgIGEgPSBzdW0zMihUMSwgVDIpO1xuICB9XG5cbiAgdGhpcy5oWzBdID0gc3VtMzIodGhpcy5oWzBdLCBhKTtcbiAgdGhpcy5oWzFdID0gc3VtMzIodGhpcy5oWzFdLCBiKTtcbiAgdGhpcy5oWzJdID0gc3VtMzIodGhpcy5oWzJdLCBjKTtcbiAgdGhpcy5oWzNdID0gc3VtMzIodGhpcy5oWzNdLCBkKTtcbiAgdGhpcy5oWzRdID0gc3VtMzIodGhpcy5oWzRdLCBlKTtcbiAgdGhpcy5oWzVdID0gc3VtMzIodGhpcy5oWzVdLCBmKTtcbiAgdGhpcy5oWzZdID0gc3VtMzIodGhpcy5oWzZdLCBnKTtcbiAgdGhpcy5oWzddID0gc3VtMzIodGhpcy5oWzddLCBoKTtcbn07XG5cblNIQTI1Ni5wcm90b3R5cGUuX2RpZ2VzdCA9IGZ1bmN0aW9uIGRpZ2VzdChlbmMpIHtcbiAgaWYgKGVuYyA9PT0gJ2hleCcpXG4gICAgcmV0dXJuIHV0aWxzLnRvSGV4MzIodGhpcy5oLCAnYmlnJyk7XG4gIGVsc2VcbiAgICByZXR1cm4gdXRpbHMuc3BsaXQzMih0aGlzLmgsICdiaWcnKTtcbn07XG5cbmZ1bmN0aW9uIFNIQTIyNCgpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNIQTIyNCkpXG4gICAgcmV0dXJuIG5ldyBTSEEyMjQoKTtcblxuICBTSEEyNTYuY2FsbCh0aGlzKTtcbiAgdGhpcy5oID0gWyAweGMxMDU5ZWQ4LCAweDM2N2NkNTA3LCAweDMwNzBkZDE3LCAweGY3MGU1OTM5LFxuICAgICAgICAgICAgIDB4ZmZjMDBiMzEsIDB4Njg1ODE1MTEsIDB4NjRmOThmYTcsIDB4YmVmYTRmYTQgXTtcbn1cbnV0aWxzLmluaGVyaXRzKFNIQTIyNCwgU0hBMjU2KTtcbmV4cG9ydHMuc2hhMjI0ID0gU0hBMjI0O1xuXG5TSEEyMjQuYmxvY2tTaXplID0gNTEyO1xuU0hBMjI0Lm91dFNpemUgPSAyMjQ7XG5TSEEyMjQuaG1hY1N0cmVuZ3RoID0gMTkyO1xuU0hBMjI0LnBhZExlbmd0aCA9IDY0O1xuXG5TSEEyMjQucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIC8vIEp1c3QgdHJ1bmNhdGUgb3V0cHV0XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaC5zbGljZSgwLCA3KSwgJ2JpZycpO1xuICBlbHNlXG4gICAgcmV0dXJuIHV0aWxzLnNwbGl0MzIodGhpcy5oLnNsaWNlKDAsIDcpLCAnYmlnJyk7XG59O1xuXG5mdW5jdGlvbiBTSEE1MTIoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTSEE1MTIpKVxuICAgIHJldHVybiBuZXcgU0hBNTEyKCk7XG5cbiAgQmxvY2tIYXNoLmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFsgMHg2YTA5ZTY2NywgMHhmM2JjYzkwOCxcbiAgICAgICAgICAgICAweGJiNjdhZTg1LCAweDg0Y2FhNzNiLFxuICAgICAgICAgICAgIDB4M2M2ZWYzNzIsIDB4ZmU5NGY4MmIsXG4gICAgICAgICAgICAgMHhhNTRmZjUzYSwgMHg1ZjFkMzZmMSxcbiAgICAgICAgICAgICAweDUxMGU1MjdmLCAweGFkZTY4MmQxLFxuICAgICAgICAgICAgIDB4OWIwNTY4OGMsIDB4MmIzZTZjMWYsXG4gICAgICAgICAgICAgMHgxZjgzZDlhYiwgMHhmYjQxYmQ2YixcbiAgICAgICAgICAgICAweDViZTBjZDE5LCAweDEzN2UyMTc5IF07XG4gIHRoaXMuayA9IHNoYTUxMl9LO1xuICB0aGlzLlcgPSBuZXcgQXJyYXkoMTYwKTtcbn1cbnV0aWxzLmluaGVyaXRzKFNIQTUxMiwgQmxvY2tIYXNoKTtcbmV4cG9ydHMuc2hhNTEyID0gU0hBNTEyO1xuXG5TSEE1MTIuYmxvY2tTaXplID0gMTAyNDtcblNIQTUxMi5vdXRTaXplID0gNTEyO1xuU0hBNTEyLmhtYWNTdHJlbmd0aCA9IDE5MjtcblNIQTUxMi5wYWRMZW5ndGggPSAxMjg7XG5cblNIQTUxMi5wcm90b3R5cGUuX3ByZXBhcmVCbG9jayA9IGZ1bmN0aW9uIF9wcmVwYXJlQmxvY2sobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICAvLyAzMiB4IDMyYml0IHdvcmRzXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMzI7IGkrKylcbiAgICBXW2ldID0gbXNnW3N0YXJ0ICsgaV07XG4gIGZvciAoOyBpIDwgVy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHZhciBjMF9oaSA9IGcxXzUxMl9oaShXW2kgLSA0XSwgV1tpIC0gM10pOyAgLy8gaSAtIDJcbiAgICB2YXIgYzBfbG8gPSBnMV81MTJfbG8oV1tpIC0gNF0sIFdbaSAtIDNdKTtcbiAgICB2YXIgYzFfaGkgPSBXW2kgLSAxNF07ICAvLyBpIC0gN1xuICAgIHZhciBjMV9sbyA9IFdbaSAtIDEzXTtcbiAgICB2YXIgYzJfaGkgPSBnMF81MTJfaGkoV1tpIC0gMzBdLCBXW2kgLSAyOV0pOyAgLy8gaSAtIDE1XG4gICAgdmFyIGMyX2xvID0gZzBfNTEyX2xvKFdbaSAtIDMwXSwgV1tpIC0gMjldKTtcbiAgICB2YXIgYzNfaGkgPSBXW2kgLSAzMl07ICAvLyBpIC0gMTZcbiAgICB2YXIgYzNfbG8gPSBXW2kgLSAzMV07XG5cbiAgICBXW2ldID0gc3VtNjRfNF9oaShjMF9oaSwgYzBfbG8sXG4gICAgICAgICAgICAgICAgICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgICAgICAgICAgICAgICAgIGMyX2hpLCBjMl9sbyxcbiAgICAgICAgICAgICAgICAgICAgICBjM19oaSwgYzNfbG8pO1xuICAgIFdbaSArIDFdID0gc3VtNjRfNF9sbyhjMF9oaSwgYzBfbG8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGMxX2hpLCBjMV9sbyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBjM19oaSwgYzNfbG8pO1xuICB9XG59O1xuXG5TSEE1MTIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiBfdXBkYXRlKG1zZywgc3RhcnQpIHtcbiAgdGhpcy5fcHJlcGFyZUJsb2NrKG1zZywgc3RhcnQpO1xuXG4gIHZhciBXID0gdGhpcy5XO1xuXG4gIHZhciBhaCA9IHRoaXMuaFswXTtcbiAgdmFyIGFsID0gdGhpcy5oWzFdO1xuICB2YXIgYmggPSB0aGlzLmhbMl07XG4gIHZhciBibCA9IHRoaXMuaFszXTtcbiAgdmFyIGNoID0gdGhpcy5oWzRdO1xuICB2YXIgY2wgPSB0aGlzLmhbNV07XG4gIHZhciBkaCA9IHRoaXMuaFs2XTtcbiAgdmFyIGRsID0gdGhpcy5oWzddO1xuICB2YXIgZWggPSB0aGlzLmhbOF07XG4gIHZhciBlbCA9IHRoaXMuaFs5XTtcbiAgdmFyIGZoID0gdGhpcy5oWzEwXTtcbiAgdmFyIGZsID0gdGhpcy5oWzExXTtcbiAgdmFyIGdoID0gdGhpcy5oWzEyXTtcbiAgdmFyIGdsID0gdGhpcy5oWzEzXTtcbiAgdmFyIGhoID0gdGhpcy5oWzE0XTtcbiAgdmFyIGhsID0gdGhpcy5oWzE1XTtcblxuICBhc3NlcnQodGhpcy5rLmxlbmd0aCA9PT0gVy5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IFcubGVuZ3RoOyBpICs9IDIpIHtcbiAgICB2YXIgYzBfaGkgPSBoaDtcbiAgICB2YXIgYzBfbG8gPSBobDtcbiAgICB2YXIgYzFfaGkgPSBzMV81MTJfaGkoZWgsIGVsKTtcbiAgICB2YXIgYzFfbG8gPSBzMV81MTJfbG8oZWgsIGVsKTtcbiAgICB2YXIgYzJfaGkgPSBjaDY0X2hpKGVoLCBlbCwgZmgsIGZsLCBnaCwgZ2wpO1xuICAgIHZhciBjMl9sbyA9IGNoNjRfbG8oZWgsIGVsLCBmaCwgZmwsIGdoLCBnbCk7XG4gICAgdmFyIGMzX2hpID0gdGhpcy5rW2ldO1xuICAgIHZhciBjM19sbyA9IHRoaXMua1tpICsgMV07XG4gICAgdmFyIGM0X2hpID0gV1tpXTtcbiAgICB2YXIgYzRfbG8gPSBXW2kgKyAxXTtcblxuICAgIHZhciBUMV9oaSA9IHN1bTY0XzVfaGkoYzBfaGksIGMwX2xvLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgYzNfaGksIGMzX2xvLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgYzRfaGksIGM0X2xvKTtcbiAgICB2YXIgVDFfbG8gPSBzdW02NF81X2xvKGMwX2hpLCBjMF9sbyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGMxX2hpLCBjMV9sbyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGMyX2hpLCBjMl9sbyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGMzX2hpLCBjM19sbyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGM0X2hpLCBjNF9sbyk7XG5cbiAgICB2YXIgYzBfaGkgPSBzMF81MTJfaGkoYWgsIGFsKTtcbiAgICB2YXIgYzBfbG8gPSBzMF81MTJfbG8oYWgsIGFsKTtcbiAgICB2YXIgYzFfaGkgPSBtYWo2NF9oaShhaCwgYWwsIGJoLCBibCwgY2gsIGNsKTtcbiAgICB2YXIgYzFfbG8gPSBtYWo2NF9sbyhhaCwgYWwsIGJoLCBibCwgY2gsIGNsKTtcblxuICAgIHZhciBUMl9oaSA9IHN1bTY0X2hpKGMwX2hpLCBjMF9sbywgYzFfaGksIGMxX2xvKTtcbiAgICB2YXIgVDJfbG8gPSBzdW02NF9sbyhjMF9oaSwgYzBfbG8sIGMxX2hpLCBjMV9sbyk7XG5cbiAgICBoaCA9IGdoO1xuICAgIGhsID0gZ2w7XG5cbiAgICBnaCA9IGZoO1xuICAgIGdsID0gZmw7XG5cbiAgICBmaCA9IGVoO1xuICAgIGZsID0gZWw7XG5cbiAgICBlaCA9IHN1bTY0X2hpKGRoLCBkbCwgVDFfaGksIFQxX2xvKTtcbiAgICBlbCA9IHN1bTY0X2xvKGRsLCBkbCwgVDFfaGksIFQxX2xvKTtcblxuICAgIGRoID0gY2g7XG4gICAgZGwgPSBjbDtcblxuICAgIGNoID0gYmg7XG4gICAgY2wgPSBibDtcblxuICAgIGJoID0gYWg7XG4gICAgYmwgPSBhbDtcblxuICAgIGFoID0gc3VtNjRfaGkoVDFfaGksIFQxX2xvLCBUMl9oaSwgVDJfbG8pO1xuICAgIGFsID0gc3VtNjRfbG8oVDFfaGksIFQxX2xvLCBUMl9oaSwgVDJfbG8pO1xuICB9XG5cbiAgc3VtNjQodGhpcy5oLCAwLCBhaCwgYWwpO1xuICBzdW02NCh0aGlzLmgsIDIsIGJoLCBibCk7XG4gIHN1bTY0KHRoaXMuaCwgNCwgY2gsIGNsKTtcbiAgc3VtNjQodGhpcy5oLCA2LCBkaCwgZGwpO1xuICBzdW02NCh0aGlzLmgsIDgsIGVoLCBlbCk7XG4gIHN1bTY0KHRoaXMuaCwgMTAsIGZoLCBmbCk7XG4gIHN1bTY0KHRoaXMuaCwgMTIsIGdoLCBnbCk7XG4gIHN1bTY0KHRoaXMuaCwgMTQsIGhoLCBobCk7XG59O1xuXG5TSEE1MTIucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaCwgJ2JpZycpO1xuICBlbHNlXG4gICAgcmV0dXJuIHV0aWxzLnNwbGl0MzIodGhpcy5oLCAnYmlnJyk7XG59O1xuXG5mdW5jdGlvbiBTSEEzODQoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTSEEzODQpKVxuICAgIHJldHVybiBuZXcgU0hBMzg0KCk7XG5cbiAgU0hBNTEyLmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFsgMHhjYmJiOWQ1ZCwgMHhjMTA1OWVkOCxcbiAgICAgICAgICAgICAweDYyOWEyOTJhLCAweDM2N2NkNTA3LFxuICAgICAgICAgICAgIDB4OTE1OTAxNWEsIDB4MzA3MGRkMTcsXG4gICAgICAgICAgICAgMHgxNTJmZWNkOCwgMHhmNzBlNTkzOSxcbiAgICAgICAgICAgICAweDY3MzMyNjY3LCAweGZmYzAwYjMxLFxuICAgICAgICAgICAgIDB4OGViNDRhODcsIDB4Njg1ODE1MTEsXG4gICAgICAgICAgICAgMHhkYjBjMmUwZCwgMHg2NGY5OGZhNyxcbiAgICAgICAgICAgICAweDQ3YjU0ODFkLCAweGJlZmE0ZmE0IF07XG59XG51dGlscy5pbmhlcml0cyhTSEEzODQsIFNIQTUxMik7XG5leHBvcnRzLnNoYTM4NCA9IFNIQTM4NDtcblxuU0hBMzg0LmJsb2NrU2l6ZSA9IDEwMjQ7XG5TSEEzODQub3V0U2l6ZSA9IDM4NDtcblNIQTM4NC5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEEzODQucGFkTGVuZ3RoID0gMTI4O1xuXG5TSEEzODQucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaC5zbGljZSgwLCAxMiksICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaC5zbGljZSgwLCAxMiksICdiaWcnKTtcbn07XG5cbmZ1bmN0aW9uIFNIQTEoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTSEExKSlcbiAgICByZXR1cm4gbmV3IFNIQTEoKTtcblxuICBCbG9ja0hhc2guY2FsbCh0aGlzKTtcbiAgdGhpcy5oID0gWyAweDY3NDUyMzAxLCAweGVmY2RhYjg5LCAweDk4YmFkY2ZlLFxuICAgICAgICAgICAgIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjAgXTtcbiAgdGhpcy5XID0gbmV3IEFycmF5KDgwKTtcbn1cblxudXRpbHMuaW5oZXJpdHMoU0hBMSwgQmxvY2tIYXNoKTtcbmV4cG9ydHMuc2hhMSA9IFNIQTE7XG5cblNIQTEuYmxvY2tTaXplID0gNTEyO1xuU0hBMS5vdXRTaXplID0gMTYwO1xuU0hBMS5obWFjU3RyZW5ndGggPSA4MDtcblNIQTEucGFkTGVuZ3RoID0gNjQ7XG5cblNIQTEucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiBfdXBkYXRlKG1zZywgc3RhcnQpIHtcbiAgdmFyIFcgPSB0aGlzLlc7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKVxuICAgIFdbaV0gPSBtc2dbc3RhcnQgKyBpXTtcblxuICBmb3IoOyBpIDwgVy5sZW5ndGg7IGkrKylcbiAgICBXW2ldID0gcm90bDMyKFdbaSAtIDNdIF4gV1tpIC0gOF0gXiBXW2kgLSAxNF0gXiBXW2kgLSAxNl0sIDEpO1xuXG4gIHZhciBhID0gdGhpcy5oWzBdO1xuICB2YXIgYiA9IHRoaXMuaFsxXTtcbiAgdmFyIGMgPSB0aGlzLmhbMl07XG4gIHZhciBkID0gdGhpcy5oWzNdO1xuICB2YXIgZSA9IHRoaXMuaFs0XTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IFcubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcyA9IH5+KGkgLyAyMCk7XG4gICAgdmFyIHQgPSBzdW0zMl81KHJvdGwzMihhLCA1KSwgZnRfMShzLCBiLCBjLCBkKSwgZSwgV1tpXSwgc2hhMV9LW3NdKTtcbiAgICBlID0gZDtcbiAgICBkID0gYztcbiAgICBjID0gcm90bDMyKGIsIDMwKTtcbiAgICBiID0gYTtcbiAgICBhID0gdDtcbiAgfVxuXG4gIHRoaXMuaFswXSA9IHN1bTMyKHRoaXMuaFswXSwgYSk7XG4gIHRoaXMuaFsxXSA9IHN1bTMyKHRoaXMuaFsxXSwgYik7XG4gIHRoaXMuaFsyXSA9IHN1bTMyKHRoaXMuaFsyXSwgYyk7XG4gIHRoaXMuaFszXSA9IHN1bTMyKHRoaXMuaFszXSwgZCk7XG4gIHRoaXMuaFs0XSA9IHN1bTMyKHRoaXMuaFs0XSwgZSk7XG59O1xuXG5TSEExLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2JpZycpO1xufTtcblxuZnVuY3Rpb24gY2gzMih4LCB5LCB6KSB7XG4gIHJldHVybiAoeCAmIHkpIF4gKCh+eCkgJiB6KTtcbn1cblxuZnVuY3Rpb24gbWFqMzIoeCwgeSwgeikge1xuICByZXR1cm4gKHggJiB5KSBeICh4ICYgeikgXiAoeSAmIHopO1xufVxuXG5mdW5jdGlvbiBwMzIoeCwgeSwgeikge1xuICByZXR1cm4geCBeIHkgXiB6O1xufVxuXG5mdW5jdGlvbiBzMF8yNTYoeCkge1xuICByZXR1cm4gcm90cjMyKHgsIDIpIF4gcm90cjMyKHgsIDEzKSBeIHJvdHIzMih4LCAyMik7XG59XG5cbmZ1bmN0aW9uIHMxXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgNikgXiByb3RyMzIoeCwgMTEpIF4gcm90cjMyKHgsIDI1KTtcbn1cblxuZnVuY3Rpb24gZzBfMjU2KHgpIHtcbiAgcmV0dXJuIHJvdHIzMih4LCA3KSBeIHJvdHIzMih4LCAxOCkgXiAoeCA+Pj4gMyk7XG59XG5cbmZ1bmN0aW9uIGcxXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgMTcpIF4gcm90cjMyKHgsIDE5KSBeICh4ID4+PiAxMCk7XG59XG5cbmZ1bmN0aW9uIGZ0XzEocywgeCwgeSwgeikge1xuICBpZiAocyA9PT0gMClcbiAgICByZXR1cm4gY2gzMih4LCB5LCB6KTtcbiAgaWYgKHMgPT09IDEgfHwgcyA9PT0gMylcbiAgICByZXR1cm4gcDMyKHgsIHksIHopO1xuICBpZiAocyA9PT0gMilcbiAgICByZXR1cm4gbWFqMzIoeCwgeSwgeik7XG59XG5cbmZ1bmN0aW9uIGNoNjRfaGkoeGgsIHhsLCB5aCwgeWwsIHpoLCB6bCkge1xuICB2YXIgciA9ICh4aCAmIHloKSBeICgofnhoKSAmIHpoKTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBjaDY0X2xvKHhoLCB4bCwgeWgsIHlsLCB6aCwgemwpIHtcbiAgdmFyIHIgPSAoeGwgJiB5bCkgXiAoKH54bCkgJiB6bCk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gbWFqNjRfaGkoeGgsIHhsLCB5aCwgeWwsIHpoLCB6bCkge1xuICB2YXIgciA9ICh4aCAmIHloKSBeICh4aCAmIHpoKSBeICh5aCAmIHpoKTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBtYWo2NF9sbyh4aCwgeGwsIHloLCB5bCwgemgsIHpsKSB7XG4gIHZhciByID0gKHhsICYgeWwpIF4gKHhsICYgemwpIF4gKHlsICYgemwpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMwXzUxMl9oaSh4aCwgeGwpIHtcbiAgdmFyIGMwX2hpID0gcm90cjY0X2hpKHhoLCB4bCwgMjgpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGwsIHhoLCAyKTsgIC8vIDM0XG4gIHZhciBjMl9oaSA9IHJvdHI2NF9oaSh4bCwgeGgsIDcpOyAgLy8gMzlcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBzMF81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDI4KTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgMik7ICAvLyAzNFxuICB2YXIgYzJfbG8gPSByb3RyNjRfbG8oeGwsIHhoLCA3KTsgIC8vIDM5XG5cbiAgdmFyIHIgPSBjMF9sbyBeIGMxX2xvIF4gYzJfbG87XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gczFfNTEyX2hpKHhoLCB4bCkge1xuICB2YXIgYzBfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCAxNCk7XG4gIHZhciBjMV9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDE4KTtcbiAgdmFyIGMyX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgOSk7ICAvLyA0MVxuXG4gIHZhciByID0gYzBfaGkgXiBjMV9oaSBeIGMyX2hpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMxXzUxMl9sbyh4aCwgeGwpIHtcbiAgdmFyIGMwX2xvID0gcm90cjY0X2xvKHhoLCB4bCwgMTQpO1xuICB2YXIgYzFfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCAxOCk7XG4gIHZhciBjMl9sbyA9IHJvdHI2NF9sbyh4bCwgeGgsIDkpOyAgLy8gNDFcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMF81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDEpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCA4KTtcbiAgdmFyIGMyX2hpID0gc2hyNjRfaGkoeGgsIHhsLCA3KTtcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMF81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDEpO1xuICB2YXIgYzFfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCA4KTtcbiAgdmFyIGMyX2xvID0gc2hyNjRfbG8oeGgsIHhsLCA3KTtcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMV81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDE5KTtcbiAgdmFyIGMxX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgMjkpOyAgLy8gNjFcbiAgdmFyIGMyX2hpID0gc2hyNjRfaGkoeGgsIHhsLCA2KTtcblxuICB2YXIgciA9IGMwX2hpIF4gYzFfaGkgXiBjMl9oaTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBnMV81MTJfbG8oeGgsIHhsKSB7XG4gIHZhciBjMF9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDE5KTtcbiAgdmFyIGMxX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgMjkpOyAgLy8gNjFcbiAgdmFyIGMyX2xvID0gc2hyNjRfbG8oeGgsIHhsLCA2KTtcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuIiwidmFyIHV0aWxzID0gZXhwb3J0cztcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmZ1bmN0aW9uIHRvQXJyYXkobXNnLCBlbmMpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkobXNnKSlcbiAgICByZXR1cm4gbXNnLnNsaWNlKCk7XG4gIGlmICghbXNnKVxuICAgIHJldHVybiBbXTtcbiAgdmFyIHJlcyA9IFtdO1xuICBpZiAodHlwZW9mIG1zZyA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAoIWVuYykge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGMgPSBtc2cuY2hhckNvZGVBdChpKTtcbiAgICAgICAgdmFyIGhpID0gYyA+PiA4O1xuICAgICAgICB2YXIgbG8gPSBjICYgMHhmZjtcbiAgICAgICAgaWYgKGhpKVxuICAgICAgICAgIHJlcy5wdXNoKGhpLCBsbyk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICByZXMucHVzaChsbyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChlbmMgPT09ICdoZXgnKSB7XG4gICAgICBtc2cgPSBtc2cucmVwbGFjZSgvW15hLXowLTldKy9pZywgJycpO1xuICAgICAgaWYgKG1zZy5sZW5ndGggJSAyICE9PSAwKVxuICAgICAgICBtc2cgPSAnMCcgKyBtc2c7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkgKz0gMilcbiAgICAgICAgcmVzLnB1c2gocGFyc2VJbnQobXNnW2ldICsgbXNnW2kgKyAxXSwgMTYpKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspXG4gICAgICByZXNbaV0gPSBtc2dbaV0gfCAwO1xuICB9XG4gIHJldHVybiByZXM7XG59XG51dGlscy50b0FycmF5ID0gdG9BcnJheTtcblxuZnVuY3Rpb24gdG9IZXgobXNnKSB7XG4gIHZhciByZXMgPSAnJztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspXG4gICAgcmVzICs9IHplcm8yKG1zZ1tpXS50b1N0cmluZygxNikpO1xuICByZXR1cm4gcmVzO1xufVxudXRpbHMudG9IZXggPSB0b0hleDtcblxuZnVuY3Rpb24gaHRvbmwodykge1xuICB2YXIgcmVzID0gKHcgPj4+IDI0KSB8XG4gICAgICAgICAgICAoKHcgPj4+IDgpICYgMHhmZjAwKSB8XG4gICAgICAgICAgICAoKHcgPDwgOCkgJiAweGZmMDAwMCkgfFxuICAgICAgICAgICAgKCh3ICYgMHhmZikgPDwgMjQpO1xuICByZXR1cm4gcmVzID4+PiAwO1xufVxudXRpbHMuaHRvbmwgPSBodG9ubDtcblxuZnVuY3Rpb24gdG9IZXgzMihtc2csIGVuZGlhbikge1xuICB2YXIgcmVzID0gJyc7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHcgPSBtc2dbaV07XG4gICAgaWYgKGVuZGlhbiA9PT0gJ2xpdHRsZScpXG4gICAgICB3ID0gaHRvbmwodyk7XG4gICAgcmVzICs9IHplcm84KHcudG9TdHJpbmcoMTYpKTtcbiAgfVxuICByZXR1cm4gcmVzO1xufVxudXRpbHMudG9IZXgzMiA9IHRvSGV4MzI7XG5cbmZ1bmN0aW9uIHplcm8yKHdvcmQpIHtcbiAgaWYgKHdvcmQubGVuZ3RoID09PSAxKVxuICAgIHJldHVybiAnMCcgKyB3b3JkO1xuICBlbHNlXG4gICAgcmV0dXJuIHdvcmQ7XG59XG51dGlscy56ZXJvMiA9IHplcm8yO1xuXG5mdW5jdGlvbiB6ZXJvOCh3b3JkKSB7XG4gIGlmICh3b3JkLmxlbmd0aCA9PT0gNylcbiAgICByZXR1cm4gJzAnICsgd29yZDtcbiAgZWxzZSBpZiAod29yZC5sZW5ndGggPT09IDYpXG4gICAgcmV0dXJuICcwMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gNSlcbiAgICByZXR1cm4gJzAwMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gNClcbiAgICByZXR1cm4gJzAwMDAnICsgd29yZDtcbiAgZWxzZSBpZiAod29yZC5sZW5ndGggPT09IDMpXG4gICAgcmV0dXJuICcwMDAwMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gMilcbiAgICByZXR1cm4gJzAwMDAwMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gMSlcbiAgICByZXR1cm4gJzAwMDAwMDAnICsgd29yZDtcbiAgZWxzZVxuICAgIHJldHVybiB3b3JkO1xufVxudXRpbHMuemVybzggPSB6ZXJvODtcblxuZnVuY3Rpb24gam9pbjMyKG1zZywgc3RhcnQsIGVuZCwgZW5kaWFuKSB7XG4gIHZhciBsZW4gPSBlbmQgLSBzdGFydDtcbiAgYXNzZXJ0KGxlbiAlIDQgPT09IDApO1xuICB2YXIgcmVzID0gbmV3IEFycmF5KGxlbiAvIDQpO1xuICBmb3IgKHZhciBpID0gMCwgayA9IHN0YXJ0OyBpIDwgcmVzLmxlbmd0aDsgaSsrLCBrICs9IDQpIHtcbiAgICB2YXIgdztcbiAgICBpZiAoZW5kaWFuID09PSAnYmlnJylcbiAgICAgIHcgPSAobXNnW2tdIDw8IDI0KSB8IChtc2dbayArIDFdIDw8IDE2KSB8IChtc2dbayArIDJdIDw8IDgpIHwgbXNnW2sgKyAzXTtcbiAgICBlbHNlXG4gICAgICB3ID0gKG1zZ1trICsgM10gPDwgMjQpIHwgKG1zZ1trICsgMl0gPDwgMTYpIHwgKG1zZ1trICsgMV0gPDwgOCkgfCBtc2dba107XG4gICAgcmVzW2ldID0gdyA+Pj4gMDtcbiAgfVxuICByZXR1cm4gcmVzO1xufVxudXRpbHMuam9pbjMyID0gam9pbjMyO1xuXG5mdW5jdGlvbiBzcGxpdDMyKG1zZywgZW5kaWFuKSB7XG4gIHZhciByZXMgPSBuZXcgQXJyYXkobXNnLmxlbmd0aCAqIDQpO1xuICBmb3IgKHZhciBpID0gMCwgayA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyssIGsgKz0gNCkge1xuICAgIHZhciBtID0gbXNnW2ldO1xuICAgIGlmIChlbmRpYW4gPT09ICdiaWcnKSB7XG4gICAgICByZXNba10gPSBtID4+PiAyNDtcbiAgICAgIHJlc1trICsgMV0gPSAobSA+Pj4gMTYpICYgMHhmZjtcbiAgICAgIHJlc1trICsgMl0gPSAobSA+Pj4gOCkgJiAweGZmO1xuICAgICAgcmVzW2sgKyAzXSA9IG0gJiAweGZmO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXNbayArIDNdID0gbSA+Pj4gMjQ7XG4gICAgICByZXNbayArIDJdID0gKG0gPj4+IDE2KSAmIDB4ZmY7XG4gICAgICByZXNbayArIDFdID0gKG0gPj4+IDgpICYgMHhmZjtcbiAgICAgIHJlc1trXSA9IG0gJiAweGZmO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzO1xufVxudXRpbHMuc3BsaXQzMiA9IHNwbGl0MzI7XG5cbmZ1bmN0aW9uIHJvdHIzMih3LCBiKSB7XG4gIHJldHVybiAodyA+Pj4gYikgfCAodyA8PCAoMzIgLSBiKSk7XG59XG51dGlscy5yb3RyMzIgPSByb3RyMzI7XG5cbmZ1bmN0aW9uIHJvdGwzMih3LCBiKSB7XG4gIHJldHVybiAodyA8PCBiKSB8ICh3ID4+PiAoMzIgLSBiKSk7XG59XG51dGlscy5yb3RsMzIgPSByb3RsMzI7XG5cbmZ1bmN0aW9uIHN1bTMyKGEsIGIpIHtcbiAgcmV0dXJuIChhICsgYikgPj4+IDA7XG59XG51dGlscy5zdW0zMiA9IHN1bTMyO1xuXG5mdW5jdGlvbiBzdW0zMl8zKGEsIGIsIGMpIHtcbiAgcmV0dXJuIChhICsgYiArIGMpID4+PiAwO1xufVxudXRpbHMuc3VtMzJfMyA9IHN1bTMyXzM7XG5cbmZ1bmN0aW9uIHN1bTMyXzQoYSwgYiwgYywgZCkge1xuICByZXR1cm4gKGEgKyBiICsgYyArIGQpID4+PiAwO1xufVxudXRpbHMuc3VtMzJfNCA9IHN1bTMyXzQ7XG5cbmZ1bmN0aW9uIHN1bTMyXzUoYSwgYiwgYywgZCwgZSkge1xuICByZXR1cm4gKGEgKyBiICsgYyArIGQgKyBlKSA+Pj4gMDtcbn1cbnV0aWxzLnN1bTMyXzUgPSBzdW0zMl81O1xuXG5mdW5jdGlvbiBhc3NlcnQoY29uZCwgbXNnKSB7XG4gIGlmICghY29uZClcbiAgICB0aHJvdyBuZXcgRXJyb3IobXNnIHx8ICdBc3NlcnRpb24gZmFpbGVkJyk7XG59XG51dGlscy5hc3NlcnQgPSBhc3NlcnQ7XG5cbnV0aWxzLmluaGVyaXRzID0gaW5oZXJpdHM7XG5cbmZ1bmN0aW9uIHN1bTY0KGJ1ZiwgcG9zLCBhaCwgYWwpIHtcbiAgdmFyIGJoID0gYnVmW3Bvc107XG4gIHZhciBibCA9IGJ1Zltwb3MgKyAxXTtcblxuICB2YXIgbG8gPSAoYWwgKyBibCkgPj4+IDA7XG4gIHZhciBoaSA9IChsbyA8IGFsID8gMSA6IDApICsgYWggKyBiaDtcbiAgYnVmW3Bvc10gPSBoaSA+Pj4gMDtcbiAgYnVmW3BvcyArIDFdID0gbG87XG59XG5leHBvcnRzLnN1bTY0ID0gc3VtNjQ7XG5cbmZ1bmN0aW9uIHN1bTY0X2hpKGFoLCBhbCwgYmgsIGJsKSB7XG4gIHZhciBsbyA9IChhbCArIGJsKSA+Pj4gMDtcbiAgdmFyIGhpID0gKGxvIDwgYWwgPyAxIDogMCkgKyBhaCArIGJoO1xuICByZXR1cm4gaGkgPj4+IDA7XG59O1xuZXhwb3J0cy5zdW02NF9oaSA9IHN1bTY0X2hpO1xuXG5mdW5jdGlvbiBzdW02NF9sbyhhaCwgYWwsIGJoLCBibCkge1xuICB2YXIgbG8gPSBhbCArIGJsO1xuICByZXR1cm4gbG8gPj4+IDA7XG59O1xuZXhwb3J0cy5zdW02NF9sbyA9IHN1bTY0X2xvO1xuXG5mdW5jdGlvbiBzdW02NF80X2hpKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wsIGRoLCBkbCkge1xuICB2YXIgY2FycnkgPSAwO1xuICB2YXIgbG8gPSBhbDtcbiAgbG8gPSAobG8gKyBibCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgYWwgPyAxIDogMDtcbiAgbG8gPSAobG8gKyBjbCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgY2wgPyAxIDogMDtcbiAgbG8gPSAobG8gKyBkbCkgPj4+IDA7XG4gIGNhcnJ5ICs9IGxvIDwgZGwgPyAxIDogMDtcblxuICB2YXIgaGkgPSBhaCArIGJoICsgY2ggKyBkaCArIGNhcnJ5O1xuICByZXR1cm4gaGkgPj4+IDA7XG59O1xuZXhwb3J0cy5zdW02NF80X2hpID0gc3VtNjRfNF9oaTtcblxuZnVuY3Rpb24gc3VtNjRfNF9sbyhhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwpIHtcbiAgdmFyIGxvID0gYWwgKyBibCArIGNsICsgZGw7XG4gIHJldHVybiBsbyA+Pj4gMDtcbn07XG5leHBvcnRzLnN1bTY0XzRfbG8gPSBzdW02NF80X2xvO1xuXG5mdW5jdGlvbiBzdW02NF81X2hpKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wsIGRoLCBkbCwgZWgsIGVsKSB7XG4gIHZhciBjYXJyeSA9IDA7XG4gIHZhciBsbyA9IGFsO1xuICBsbyA9IChsbyArIGJsKSA+Pj4gMDtcbiAgY2FycnkgKz0gbG8gPCBhbCA/IDEgOiAwO1xuICBsbyA9IChsbyArIGNsKSA+Pj4gMDtcbiAgY2FycnkgKz0gbG8gPCBjbCA/IDEgOiAwO1xuICBsbyA9IChsbyArIGRsKSA+Pj4gMDtcbiAgY2FycnkgKz0gbG8gPCBkbCA/IDEgOiAwO1xuICBsbyA9IChsbyArIGVsKSA+Pj4gMDtcbiAgY2FycnkgKz0gbG8gPCBlbCA/IDEgOiAwO1xuXG4gIHZhciBoaSA9IGFoICsgYmggKyBjaCArIGRoICsgZWggKyBjYXJyeTtcbiAgcmV0dXJuIGhpID4+PiAwO1xufTtcbmV4cG9ydHMuc3VtNjRfNV9oaSA9IHN1bTY0XzVfaGk7XG5cbmZ1bmN0aW9uIHN1bTY0XzVfbG8oYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCwgZGgsIGRsLCBlaCwgZWwpIHtcbiAgdmFyIGxvID0gYWwgKyBibCArIGNsICsgZGwgKyBlbDtcblxuICByZXR1cm4gbG8gPj4+IDA7XG59O1xuZXhwb3J0cy5zdW02NF81X2xvID0gc3VtNjRfNV9sbztcblxuZnVuY3Rpb24gcm90cjY0X2hpKGFoLCBhbCwgbnVtKSB7XG4gIHZhciByID0gKGFsIDw8ICgzMiAtIG51bSkpIHwgKGFoID4+PiBudW0pO1xuICByZXR1cm4gciA+Pj4gMDtcbn07XG5leHBvcnRzLnJvdHI2NF9oaSA9IHJvdHI2NF9oaTtcblxuZnVuY3Rpb24gcm90cjY0X2xvKGFoLCBhbCwgbnVtKSB7XG4gIHZhciByID0gKGFoIDw8ICgzMiAtIG51bSkpIHwgKGFsID4+PiBudW0pO1xuICByZXR1cm4gciA+Pj4gMDtcbn07XG5leHBvcnRzLnJvdHI2NF9sbyA9IHJvdHI2NF9sbztcblxuZnVuY3Rpb24gc2hyNjRfaGkoYWgsIGFsLCBudW0pIHtcbiAgcmV0dXJuIGFoID4+PiBudW07XG59O1xuZXhwb3J0cy5zaHI2NF9oaSA9IHNocjY0X2hpO1xuXG5mdW5jdGlvbiBzaHI2NF9sbyhhaCwgYWwsIG51bSkge1xuICB2YXIgciA9IChhaCA8PCAoMzIgLSBudW0pKSB8IChhbCA+Pj4gbnVtKTtcbiAgcmV0dXJuIHIgPj4+IDA7XG59O1xuZXhwb3J0cy5zaHI2NF9sbyA9IHNocjY0X2xvO1xuIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcIm5hbWVcIjogXCJlbGxpcHRpY1wiLFxuICBcInZlcnNpb25cIjogXCI2LjIuM1wiLFxuICBcImRlc2NyaXB0aW9uXCI6IFwiRUMgY3J5cHRvZ3JhcGh5XCIsXG4gIFwibWFpblwiOiBcImxpYi9lbGxpcHRpYy5qc1wiLFxuICBcImZpbGVzXCI6IFtcbiAgICBcImxpYlwiXG4gIF0sXG4gIFwic2NyaXB0c1wiOiB7XG4gICAgXCJjb3ZlcmFnZVwiOiBcIm5wbSBydW4gdW5pdCAtLWNvdmVyYWdlXCIsXG4gICAgXCJjb3ZlcmFsbHNcIjogXCJucG0gcnVuIGNvdmVyYWdlICYmIGNhdCAuL2NvdmVyYWdlL2xjb3YuaW5mbyB8IGNvdmVyYWxsc1wiLFxuICAgIFwianNjc1wiOiBcImpzY3MgYmVuY2htYXJrcy8qLmpzIGxpYi8qLmpzIGxpYi8qKi8qLmpzIGxpYi8qKi8qKi8qLmpzIHRlc3QvKi5qc1wiLFxuICAgIFwianNoaW50XCI6IFwianNjcyBiZW5jaG1hcmtzLyouanMgbGliLyouanMgbGliLyoqLyouanMgbGliLyoqLyoqLyouanMgdGVzdC8qLmpzXCIsXG4gICAgXCJsaW50XCI6IFwibnBtIHJ1biBqc2NzICYmIG5wbSBydW4ganNoaW50XCIsXG4gICAgXCJ0ZXN0XCI6IFwibnBtIHJ1biBsaW50ICYmIG5wbSBydW4gdW5pdFwiLFxuICAgIFwidW5pdFwiOiBcImlzdGFuYnVsIHRlc3QgX21vY2hhIC0tcmVwb3J0ZXI9c3BlYyB0ZXN0LyotdGVzdC5qc1wiXG4gIH0sXG4gIFwicmVwb3NpdG9yeVwiOiB7XG4gICAgXCJ0eXBlXCI6IFwiZ2l0XCIsXG4gICAgXCJ1cmxcIjogXCJnaXQrc3NoOi8vZ2l0QGdpdGh1Yi5jb20vaW5kdXRueS9lbGxpcHRpYy5naXRcIlxuICB9LFxuICBcImtleXdvcmRzXCI6IFtcbiAgICBcIkVDXCIsXG4gICAgXCJFbGxpcHRpY1wiLFxuICAgIFwiY3VydmVcIixcbiAgICBcIkNyeXB0b2dyYXBoeVwiXG4gIF0sXG4gIFwiYXV0aG9yXCI6IHtcbiAgICBcIm5hbWVcIjogXCJGZWRvciBJbmR1dG55XCIsXG4gICAgXCJlbWFpbFwiOiBcImZlZG9yQGluZHV0bnkuY29tXCJcbiAgfSxcbiAgXCJsaWNlbnNlXCI6IFwiTUlUXCIsXG4gIFwiYnVnc1wiOiB7XG4gICAgXCJ1cmxcIjogXCJodHRwczovL2dpdGh1Yi5jb20vaW5kdXRueS9lbGxpcHRpYy9pc3N1ZXNcIlxuICB9LFxuICBcImhvbWVwYWdlXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL2luZHV0bnkvZWxsaXB0aWNcIixcbiAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiY292ZXJhbGxzXCI6IFwiXjIuMTEuM1wiLFxuICAgIFwiaXN0YW5idWxcIjogXCJeMC40LjJcIixcbiAgICBcImpzY3NcIjogXCJeMi45LjBcIixcbiAgICBcImpzaGludFwiOiBcIl4yLjYuMFwiLFxuICAgIFwibW9jaGFcIjogXCJeMi4xLjBcIlxuICB9LFxuICBcImRlcGVuZGVuY2llc1wiOiB7XG4gICAgXCJibi5qc1wiOiBcIl40LjAuMFwiLFxuICAgIFwiYnJvcmFuZFwiOiBcIl4xLjAuMVwiLFxuICAgIFwiaGFzaC5qc1wiOiBcIl4xLjAuMFwiLFxuICAgIFwiaW5oZXJpdHNcIjogXCJeMi4wLjFcIlxuICB9LFxuICBcImdpdEhlYWRcIjogXCJjMzJmMjBiMjJiNDIwZWI2YWYzYzZkZGEyODk2M2RlYjdmYWNmODIzXCIsXG4gIFwiX2lkXCI6IFwiZWxsaXB0aWNANi4yLjNcIixcbiAgXCJfc2hhc3VtXCI6IFwiMThlNDZkNzMwNmIwOTUxMjc1YTJkNDIwNjMyNzBhMTRiNzRlYmU5OVwiLFxuICBcIl9mcm9tXCI6IFwiZWxsaXB0aWNAXjYuMC4wXCIsXG4gIFwiX25wbVZlcnNpb25cIjogXCIzLjMuMTJcIixcbiAgXCJfbm9kZVZlcnNpb25cIjogXCI1LjQuMVwiLFxuICBcIl9ucG1Vc2VyXCI6IHtcbiAgICBcIm5hbWVcIjogXCJpbmR1dG55XCIsXG4gICAgXCJlbWFpbFwiOiBcImZlZG9yQGluZHV0bnkuY29tXCJcbiAgfSxcbiAgXCJkaXN0XCI6IHtcbiAgICBcInNoYXN1bVwiOiBcIjE4ZTQ2ZDczMDZiMDk1MTI3NWEyZDQyMDYzMjcwYTE0Yjc0ZWJlOTlcIixcbiAgICBcInRhcmJhbGxcIjogXCJodHRwOi8vcmVnaXN0cnkubnBtanMub3JnL2VsbGlwdGljLy0vZWxsaXB0aWMtNi4yLjMudGd6XCJcbiAgfSxcbiAgXCJtYWludGFpbmVyc1wiOiBbXG4gICAge1xuICAgICAgXCJuYW1lXCI6IFwiaW5kdXRueVwiLFxuICAgICAgXCJlbWFpbFwiOiBcImZlZG9yQGluZHV0bnkuY29tXCJcbiAgICB9XG4gIF0sXG4gIFwiZGlyZWN0b3JpZXNcIjoge30sXG4gIFwiX3Jlc29sdmVkXCI6IFwiaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcvZWxsaXB0aWMvLS9lbGxpcHRpYy02LjIuMy50Z3pcIlxufVxuIiwibW9kdWxlLmV4cG9ydHM9e1wiMi4xNi44NDAuMS4xMDEuMy40LjEuMVwiOiBcImFlcy0xMjgtZWNiXCIsXG5cIjIuMTYuODQwLjEuMTAxLjMuNC4xLjJcIjogXCJhZXMtMTI4LWNiY1wiLFxuXCIyLjE2Ljg0MC4xLjEwMS4zLjQuMS4zXCI6IFwiYWVzLTEyOC1vZmJcIixcblwiMi4xNi44NDAuMS4xMDEuMy40LjEuNFwiOiBcImFlcy0xMjgtY2ZiXCIsXG5cIjIuMTYuODQwLjEuMTAxLjMuNC4xLjIxXCI6IFwiYWVzLTE5Mi1lY2JcIixcblwiMi4xNi44NDAuMS4xMDEuMy40LjEuMjJcIjogXCJhZXMtMTkyLWNiY1wiLFxuXCIyLjE2Ljg0MC4xLjEwMS4zLjQuMS4yM1wiOiBcImFlcy0xOTItb2ZiXCIsXG5cIjIuMTYuODQwLjEuMTAxLjMuNC4xLjI0XCI6IFwiYWVzLTE5Mi1jZmJcIixcblwiMi4xNi44NDAuMS4xMDEuMy40LjEuNDFcIjogXCJhZXMtMjU2LWVjYlwiLFxuXCIyLjE2Ljg0MC4xLjEwMS4zLjQuMS40MlwiOiBcImFlcy0yNTYtY2JjXCIsXG5cIjIuMTYuODQwLjEuMTAxLjMuNC4xLjQzXCI6IFwiYWVzLTI1Ni1vZmJcIixcblwiMi4xNi44NDAuMS4xMDEuMy40LjEuNDRcIjogXCJhZXMtMjU2LWNmYlwiXG59IiwiLy8gZnJvbSBodHRwczovL2dpdGh1Yi5jb20vaW5kdXRueS9zZWxmLXNpZ25lZC9ibG9iL2doLXBhZ2VzL2xpYi9hc24xLmpzXG4vLyBGZWRvciwgeW91IGFyZSBhbWF6aW5nLlxuXG52YXIgYXNuMSA9IHJlcXVpcmUoJ2FzbjEuanMnKVxuXG52YXIgUlNBUHJpdmF0ZUtleSA9IGFzbjEuZGVmaW5lKCdSU0FQcml2YXRlS2V5JywgZnVuY3Rpb24gKCkge1xuICB0aGlzLnNlcSgpLm9iaihcbiAgICB0aGlzLmtleSgndmVyc2lvbicpLmludCgpLFxuICAgIHRoaXMua2V5KCdtb2R1bHVzJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3B1YmxpY0V4cG9uZW50JykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3ByaXZhdGVFeHBvbmVudCcpLmludCgpLFxuICAgIHRoaXMua2V5KCdwcmltZTEnKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncHJpbWUyJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ2V4cG9uZW50MScpLmludCgpLFxuICAgIHRoaXMua2V5KCdleHBvbmVudDInKS5pbnQoKSxcbiAgICB0aGlzLmtleSgnY29lZmZpY2llbnQnKS5pbnQoKVxuICApXG59KVxuZXhwb3J0cy5SU0FQcml2YXRlS2V5ID0gUlNBUHJpdmF0ZUtleVxuXG52YXIgUlNBUHVibGljS2V5ID0gYXNuMS5kZWZpbmUoJ1JTQVB1YmxpY0tleScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ21vZHVsdXMnKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncHVibGljRXhwb25lbnQnKS5pbnQoKVxuICApXG59KVxuZXhwb3J0cy5SU0FQdWJsaWNLZXkgPSBSU0FQdWJsaWNLZXlcblxudmFyIFB1YmxpY0tleSA9IGFzbjEuZGVmaW5lKCdTdWJqZWN0UHVibGljS2V5SW5mbycsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ2FsZ29yaXRobScpLnVzZShBbGdvcml0aG1JZGVudGlmaWVyKSxcbiAgICB0aGlzLmtleSgnc3ViamVjdFB1YmxpY0tleScpLmJpdHN0cigpXG4gIClcbn0pXG5leHBvcnRzLlB1YmxpY0tleSA9IFB1YmxpY0tleVxuXG52YXIgQWxnb3JpdGhtSWRlbnRpZmllciA9IGFzbjEuZGVmaW5lKCdBbGdvcml0aG1JZGVudGlmaWVyJywgZnVuY3Rpb24gKCkge1xuICB0aGlzLnNlcSgpLm9iaihcbiAgICB0aGlzLmtleSgnYWxnb3JpdGhtJykub2JqaWQoKSxcbiAgICB0aGlzLmtleSgnbm9uZScpLm51bGxfKCkub3B0aW9uYWwoKSxcbiAgICB0aGlzLmtleSgnY3VydmUnKS5vYmppZCgpLm9wdGlvbmFsKCksXG4gICAgdGhpcy5rZXkoJ3BhcmFtcycpLnNlcSgpLm9iaihcbiAgICAgIHRoaXMua2V5KCdwJykuaW50KCksXG4gICAgICB0aGlzLmtleSgncScpLmludCgpLFxuICAgICAgdGhpcy5rZXkoJ2cnKS5pbnQoKVxuICAgICkub3B0aW9uYWwoKVxuICApXG59KVxuXG52YXIgUHJpdmF0ZUtleUluZm8gPSBhc24xLmRlZmluZSgnUHJpdmF0ZUtleUluZm8nLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCd2ZXJzaW9uJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ2FsZ29yaXRobScpLnVzZShBbGdvcml0aG1JZGVudGlmaWVyKSxcbiAgICB0aGlzLmtleSgnc3ViamVjdFByaXZhdGVLZXknKS5vY3RzdHIoKVxuICApXG59KVxuZXhwb3J0cy5Qcml2YXRlS2V5ID0gUHJpdmF0ZUtleUluZm9cbnZhciBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyA9IGFzbjEuZGVmaW5lKCdFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbycsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ2FsZ29yaXRobScpLnNlcSgpLm9iaihcbiAgICAgIHRoaXMua2V5KCdpZCcpLm9iamlkKCksXG4gICAgICB0aGlzLmtleSgnZGVjcnlwdCcpLnNlcSgpLm9iaihcbiAgICAgICAgdGhpcy5rZXkoJ2tkZScpLnNlcSgpLm9iaihcbiAgICAgICAgICB0aGlzLmtleSgnaWQnKS5vYmppZCgpLFxuICAgICAgICAgIHRoaXMua2V5KCdrZGVwYXJhbXMnKS5zZXEoKS5vYmooXG4gICAgICAgICAgICB0aGlzLmtleSgnc2FsdCcpLm9jdHN0cigpLFxuICAgICAgICAgICAgdGhpcy5rZXkoJ2l0ZXJzJykuaW50KClcbiAgICAgICAgICApXG4gICAgICAgICksXG4gICAgICAgIHRoaXMua2V5KCdjaXBoZXInKS5zZXEoKS5vYmooXG4gICAgICAgICAgdGhpcy5rZXkoJ2FsZ28nKS5vYmppZCgpLFxuICAgICAgICAgIHRoaXMua2V5KCdpdicpLm9jdHN0cigpXG4gICAgICAgIClcbiAgICAgIClcbiAgICApLFxuICAgIHRoaXMua2V5KCdzdWJqZWN0UHJpdmF0ZUtleScpLm9jdHN0cigpXG4gIClcbn0pXG5cbmV4cG9ydHMuRW5jcnlwdGVkUHJpdmF0ZUtleSA9IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvXG5cbnZhciBEU0FQcml2YXRlS2V5ID0gYXNuMS5kZWZpbmUoJ0RTQVByaXZhdGVLZXknLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCd2ZXJzaW9uJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3AnKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncScpLmludCgpLFxuICAgIHRoaXMua2V5KCdnJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3B1Yl9rZXknKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncHJpdl9rZXknKS5pbnQoKVxuICApXG59KVxuZXhwb3J0cy5EU0FQcml2YXRlS2V5ID0gRFNBUHJpdmF0ZUtleVxuXG5leHBvcnRzLkRTQXBhcmFtID0gYXNuMS5kZWZpbmUoJ0RTQXBhcmFtJywgZnVuY3Rpb24gKCkge1xuICB0aGlzLmludCgpXG59KVxudmFyIEVDUHJpdmF0ZUtleSA9IGFzbjEuZGVmaW5lKCdFQ1ByaXZhdGVLZXknLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCd2ZXJzaW9uJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3ByaXZhdGVLZXknKS5vY3RzdHIoKSxcbiAgICB0aGlzLmtleSgncGFyYW1ldGVycycpLm9wdGlvbmFsKCkuZXhwbGljaXQoMCkudXNlKEVDUGFyYW1ldGVycyksXG4gICAgdGhpcy5rZXkoJ3B1YmxpY0tleScpLm9wdGlvbmFsKCkuZXhwbGljaXQoMSkuYml0c3RyKClcbiAgKVxufSlcbmV4cG9ydHMuRUNQcml2YXRlS2V5ID0gRUNQcml2YXRlS2V5XG52YXIgRUNQYXJhbWV0ZXJzID0gYXNuMS5kZWZpbmUoJ0VDUGFyYW1ldGVycycsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5jaG9pY2Uoe1xuICAgIG5hbWVkQ3VydmU6IHRoaXMub2JqaWQoKVxuICB9KVxufSlcblxuZXhwb3J0cy5zaWduYXR1cmUgPSBhc24xLmRlZmluZSgnc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICB0aGlzLnNlcSgpLm9iaihcbiAgICB0aGlzLmtleSgncicpLmludCgpLFxuICAgIHRoaXMua2V5KCdzJykuaW50KClcbiAgKVxufSlcbiIsIi8vIGFkYXB0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vYXBhdGlsL3BlbXN0cmlwXG52YXIgZmluZFByb2MgPSAvUHJvYy1UeXBlOiA0LEVOQ1JZUFRFRFxccj9cXG5ERUstSW5mbzogQUVTLSgoPzoxMjgpfCg/OjE5Mil8KD86MjU2KSktQ0JDLChbMC05QS1IXSspXFxyP1xcblxccj9cXG4oWzAtOUEtelxcblxcclxcK1xcL1xcPV0rKVxccj9cXG4vbVxudmFyIHN0YXJ0UmVnZXggPSAvXi0tLS0tQkVHSU4gKC4qKSBLRVktLS0tLVxccj9cXG4vbVxudmFyIGZ1bGxSZWdleCA9IC9eLS0tLS1CRUdJTiAoLiopIEtFWS0tLS0tXFxyP1xcbihbMC05QS16XFxuXFxyXFwrXFwvXFw9XSspXFxyP1xcbi0tLS0tRU5EIFxcMSBLRVktLS0tLSQvbVxudmFyIGV2cCA9IHJlcXVpcmUoJ2V2cF9ieXRlc3Rva2V5JylcbnZhciBjaXBoZXJzID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1hZXMnKVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2tleSwgcGFzc3dvcmQpIHtcbiAgdmFyIGtleSA9IG9rZXkudG9TdHJpbmcoKVxuICB2YXIgbWF0Y2ggPSBrZXkubWF0Y2goZmluZFByb2MpXG4gIHZhciBkZWNyeXB0ZWRcbiAgaWYgKCFtYXRjaCkge1xuICAgIHZhciBtYXRjaDIgPSBrZXkubWF0Y2goZnVsbFJlZ2V4KVxuICAgIGRlY3J5cHRlZCA9IG5ldyBCdWZmZXIobWF0Y2gyWzJdLnJlcGxhY2UoL1xccj9cXG4vZywgJycpLCAnYmFzZTY0JylcbiAgfSBlbHNlIHtcbiAgICB2YXIgc3VpdGUgPSAnYWVzJyArIG1hdGNoWzFdXG4gICAgdmFyIGl2ID0gbmV3IEJ1ZmZlcihtYXRjaFsyXSwgJ2hleCcpXG4gICAgdmFyIGNpcGhlclRleHQgPSBuZXcgQnVmZmVyKG1hdGNoWzNdLnJlcGxhY2UoL1xccj9cXG4vZywgJycpLCAnYmFzZTY0JylcbiAgICB2YXIgY2lwaGVyS2V5ID0gZXZwKHBhc3N3b3JkLCBpdi5zbGljZSgwLCA4KSwgcGFyc2VJbnQobWF0Y2hbMV0sIDEwKSkua2V5XG4gICAgdmFyIG91dCA9IFtdXG4gICAgdmFyIGNpcGhlciA9IGNpcGhlcnMuY3JlYXRlRGVjaXBoZXJpdihzdWl0ZSwgY2lwaGVyS2V5LCBpdilcbiAgICBvdXQucHVzaChjaXBoZXIudXBkYXRlKGNpcGhlclRleHQpKVxuICAgIG91dC5wdXNoKGNpcGhlci5maW5hbCgpKVxuICAgIGRlY3J5cHRlZCA9IEJ1ZmZlci5jb25jYXQob3V0KVxuICB9XG4gIHZhciB0YWcgPSBrZXkubWF0Y2goc3RhcnRSZWdleClbMV0gKyAnIEtFWSdcbiAgcmV0dXJuIHtcbiAgICB0YWc6IHRhZyxcbiAgICBkYXRhOiBkZWNyeXB0ZWRcbiAgfVxufVxuIiwidmFyIGFzbjEgPSByZXF1aXJlKCcuL2FzbjEnKVxudmFyIGFlc2lkID0gcmVxdWlyZSgnLi9hZXNpZC5qc29uJylcbnZhciBmaXhQcm9jID0gcmVxdWlyZSgnLi9maXhQcm9jJylcbnZhciBjaXBoZXJzID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1hZXMnKVxudmFyIGNvbXBhdCA9IHJlcXVpcmUoJ3Bia2RmMicpXG5tb2R1bGUuZXhwb3J0cyA9IHBhcnNlS2V5c1xuXG5mdW5jdGlvbiBwYXJzZUtleXMgKGJ1ZmZlcikge1xuICB2YXIgcGFzc3dvcmRcbiAgaWYgKHR5cGVvZiBidWZmZXIgPT09ICdvYmplY3QnICYmICFCdWZmZXIuaXNCdWZmZXIoYnVmZmVyKSkge1xuICAgIHBhc3N3b3JkID0gYnVmZmVyLnBhc3NwaHJhc2VcbiAgICBidWZmZXIgPSBidWZmZXIua2V5XG4gIH1cbiAgaWYgKHR5cGVvZiBidWZmZXIgPT09ICdzdHJpbmcnKSB7XG4gICAgYnVmZmVyID0gbmV3IEJ1ZmZlcihidWZmZXIpXG4gIH1cblxuICB2YXIgc3RyaXBwZWQgPSBmaXhQcm9jKGJ1ZmZlciwgcGFzc3dvcmQpXG5cbiAgdmFyIHR5cGUgPSBzdHJpcHBlZC50YWdcbiAgdmFyIGRhdGEgPSBzdHJpcHBlZC5kYXRhXG4gIHZhciBzdWJ0eXBlLCBuZGF0YVxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdQVUJMSUMgS0VZJzpcbiAgICAgIG5kYXRhID0gYXNuMS5QdWJsaWNLZXkuZGVjb2RlKGRhdGEsICdkZXInKVxuICAgICAgc3VidHlwZSA9IG5kYXRhLmFsZ29yaXRobS5hbGdvcml0aG0uam9pbignLicpXG4gICAgICBzd2l0Y2ggKHN1YnR5cGUpIHtcbiAgICAgICAgY2FzZSAnMS4yLjg0MC4xMTM1NDkuMS4xLjEnOlxuICAgICAgICAgIHJldHVybiBhc24xLlJTQVB1YmxpY0tleS5kZWNvZGUobmRhdGEuc3ViamVjdFB1YmxpY0tleS5kYXRhLCAnZGVyJylcbiAgICAgICAgY2FzZSAnMS4yLjg0MC4xMDA0NS4yLjEnOlxuICAgICAgICAgIG5kYXRhLnN1YmplY3RQcml2YXRlS2V5ID0gbmRhdGEuc3ViamVjdFB1YmxpY0tleVxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAnZWMnLFxuICAgICAgICAgICAgZGF0YTogbmRhdGFcbiAgICAgICAgICB9XG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTAwNDAuNC4xJzpcbiAgICAgICAgICBuZGF0YS5hbGdvcml0aG0ucGFyYW1zLnB1Yl9rZXkgPSBhc24xLkRTQXBhcmFtLmRlY29kZShuZGF0YS5zdWJqZWN0UHVibGljS2V5LmRhdGEsICdkZXInKVxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAnZHNhJyxcbiAgICAgICAgICAgIGRhdGE6IG5kYXRhLmFsZ29yaXRobS5wYXJhbXNcbiAgICAgICAgICB9XG4gICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcigndW5rbm93biBrZXkgaWQgJyArIHN1YnR5cGUpXG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24ga2V5IHR5cGUgJyArIHR5cGUpXG4gICAgY2FzZSAnRU5DUllQVEVEIFBSSVZBVEUgS0VZJzpcbiAgICAgIGRhdGEgPSBhc24xLkVuY3J5cHRlZFByaXZhdGVLZXkuZGVjb2RlKGRhdGEsICdkZXInKVxuICAgICAgZGF0YSA9IGRlY3J5cHQoZGF0YSwgcGFzc3dvcmQpXG4gICAgICAvLyBmYWxscyB0aHJvdWdoXG4gICAgY2FzZSAnUFJJVkFURSBLRVknOlxuICAgICAgbmRhdGEgPSBhc24xLlByaXZhdGVLZXkuZGVjb2RlKGRhdGEsICdkZXInKVxuICAgICAgc3VidHlwZSA9IG5kYXRhLmFsZ29yaXRobS5hbGdvcml0aG0uam9pbignLicpXG4gICAgICBzd2l0Y2ggKHN1YnR5cGUpIHtcbiAgICAgICAgY2FzZSAnMS4yLjg0MC4xMTM1NDkuMS4xLjEnOlxuICAgICAgICAgIHJldHVybiBhc24xLlJTQVByaXZhdGVLZXkuZGVjb2RlKG5kYXRhLnN1YmplY3RQcml2YXRlS2V5LCAnZGVyJylcbiAgICAgICAgY2FzZSAnMS4yLjg0MC4xMDA0NS4yLjEnOlxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjdXJ2ZTogbmRhdGEuYWxnb3JpdGhtLmN1cnZlLFxuICAgICAgICAgICAgcHJpdmF0ZUtleTogYXNuMS5FQ1ByaXZhdGVLZXkuZGVjb2RlKG5kYXRhLnN1YmplY3RQcml2YXRlS2V5LCAnZGVyJykucHJpdmF0ZUtleVxuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAnMS4yLjg0MC4xMDA0MC40LjEnOlxuICAgICAgICAgIG5kYXRhLmFsZ29yaXRobS5wYXJhbXMucHJpdl9rZXkgPSBhc24xLkRTQXBhcmFtLmRlY29kZShuZGF0YS5zdWJqZWN0UHJpdmF0ZUtleSwgJ2RlcicpXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdkc2EnLFxuICAgICAgICAgICAgcGFyYW1zOiBuZGF0YS5hbGdvcml0aG0ucGFyYW1zXG4gICAgICAgICAgfVxuICAgICAgICBkZWZhdWx0OiB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24ga2V5IGlkICcgKyBzdWJ0eXBlKVxuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGtleSB0eXBlICcgKyB0eXBlKVxuICAgIGNhc2UgJ1JTQSBQVUJMSUMgS0VZJzpcbiAgICAgIHJldHVybiBhc24xLlJTQVB1YmxpY0tleS5kZWNvZGUoZGF0YSwgJ2RlcicpXG4gICAgY2FzZSAnUlNBIFBSSVZBVEUgS0VZJzpcbiAgICAgIHJldHVybiBhc24xLlJTQVByaXZhdGVLZXkuZGVjb2RlKGRhdGEsICdkZXInKVxuICAgIGNhc2UgJ0RTQSBQUklWQVRFIEtFWSc6XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnZHNhJyxcbiAgICAgICAgcGFyYW1zOiBhc24xLkRTQVByaXZhdGVLZXkuZGVjb2RlKGRhdGEsICdkZXInKVxuICAgICAgfVxuICAgIGNhc2UgJ0VDIFBSSVZBVEUgS0VZJzpcbiAgICAgIGRhdGEgPSBhc24xLkVDUHJpdmF0ZUtleS5kZWNvZGUoZGF0YSwgJ2RlcicpXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjdXJ2ZTogZGF0YS5wYXJhbWV0ZXJzLnZhbHVlLFxuICAgICAgICBwcml2YXRlS2V5OiBkYXRhLnByaXZhdGVLZXlcbiAgICAgIH1cbiAgICBkZWZhdWx0OiB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24ga2V5IHR5cGUgJyArIHR5cGUpXG4gIH1cbn1cbnBhcnNlS2V5cy5zaWduYXR1cmUgPSBhc24xLnNpZ25hdHVyZVxuZnVuY3Rpb24gZGVjcnlwdCAoZGF0YSwgcGFzc3dvcmQpIHtcbiAgdmFyIHNhbHQgPSBkYXRhLmFsZ29yaXRobS5kZWNyeXB0LmtkZS5rZGVwYXJhbXMuc2FsdFxuICB2YXIgaXRlcnMgPSBwYXJzZUludChkYXRhLmFsZ29yaXRobS5kZWNyeXB0LmtkZS5rZGVwYXJhbXMuaXRlcnMudG9TdHJpbmcoKSwgMTApXG4gIHZhciBhbGdvID0gYWVzaWRbZGF0YS5hbGdvcml0aG0uZGVjcnlwdC5jaXBoZXIuYWxnby5qb2luKCcuJyldXG4gIHZhciBpdiA9IGRhdGEuYWxnb3JpdGhtLmRlY3J5cHQuY2lwaGVyLml2XG4gIHZhciBjaXBoZXJUZXh0ID0gZGF0YS5zdWJqZWN0UHJpdmF0ZUtleVxuICB2YXIga2V5bGVuID0gcGFyc2VJbnQoYWxnby5zcGxpdCgnLScpWzFdLCAxMCkgLyA4XG4gIHZhciBrZXkgPSBjb21wYXQucGJrZGYyU3luYyhwYXNzd29yZCwgc2FsdCwgaXRlcnMsIGtleWxlbilcbiAgdmFyIGNpcGhlciA9IGNpcGhlcnMuY3JlYXRlRGVjaXBoZXJpdihhbGdvLCBrZXksIGl2KVxuICB2YXIgb3V0ID0gW11cbiAgb3V0LnB1c2goY2lwaGVyLnVwZGF0ZShjaXBoZXJUZXh0KSlcbiAgb3V0LnB1c2goY2lwaGVyLmZpbmFsKCkpXG4gIHJldHVybiBCdWZmZXIuY29uY2F0KG91dClcbn1cbiIsInZhciBhc24xID0gZXhwb3J0cztcblxuYXNuMS5iaWdudW0gPSByZXF1aXJlKCdibi5qcycpO1xuXG5hc24xLmRlZmluZSA9IHJlcXVpcmUoJy4vYXNuMS9hcGknKS5kZWZpbmU7XG5hc24xLmJhc2UgPSByZXF1aXJlKCcuL2FzbjEvYmFzZScpO1xuYXNuMS5jb25zdGFudHMgPSByZXF1aXJlKCcuL2FzbjEvY29uc3RhbnRzJyk7XG5hc24xLmRlY29kZXJzID0gcmVxdWlyZSgnLi9hc24xL2RlY29kZXJzJyk7XG5hc24xLmVuY29kZXJzID0gcmVxdWlyZSgnLi9hc24xL2VuY29kZXJzJyk7XG4iLCJ2YXIgYXNuMSA9IHJlcXVpcmUoJy4uL2FzbjEnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbnZhciBhcGkgPSBleHBvcnRzO1xuXG5hcGkuZGVmaW5lID0gZnVuY3Rpb24gZGVmaW5lKG5hbWUsIGJvZHkpIHtcbiAgcmV0dXJuIG5ldyBFbnRpdHkobmFtZSwgYm9keSk7XG59O1xuXG5mdW5jdGlvbiBFbnRpdHkobmFtZSwgYm9keSkge1xuICB0aGlzLm5hbWUgPSBuYW1lO1xuICB0aGlzLmJvZHkgPSBib2R5O1xuXG4gIHRoaXMuZGVjb2RlcnMgPSB7fTtcbiAgdGhpcy5lbmNvZGVycyA9IHt9O1xufTtcblxuRW50aXR5LnByb3RvdHlwZS5fY3JlYXRlTmFtZWQgPSBmdW5jdGlvbiBjcmVhdGVOYW1lZChiYXNlKSB7XG4gIHZhciBuYW1lZDtcbiAgdHJ5IHtcbiAgICBuYW1lZCA9IHJlcXVpcmUoJ3ZtJykucnVuSW5UaGlzQ29udGV4dChcbiAgICAgICcoZnVuY3Rpb24gJyArIHRoaXMubmFtZSArICcoZW50aXR5KSB7XFxuJyArXG4gICAgICAnICB0aGlzLl9pbml0TmFtZWQoZW50aXR5KTtcXG4nICtcbiAgICAgICd9KSdcbiAgICApO1xuICB9IGNhdGNoIChlKSB7XG4gICAgbmFtZWQgPSBmdW5jdGlvbiAoZW50aXR5KSB7XG4gICAgICB0aGlzLl9pbml0TmFtZWQoZW50aXR5KTtcbiAgICB9O1xuICB9XG4gIGluaGVyaXRzKG5hbWVkLCBiYXNlKTtcbiAgbmFtZWQucHJvdG90eXBlLl9pbml0TmFtZWQgPSBmdW5jdGlvbiBpbml0bmFtZWQoZW50aXR5KSB7XG4gICAgYmFzZS5jYWxsKHRoaXMsIGVudGl0eSk7XG4gIH07XG5cbiAgcmV0dXJuIG5ldyBuYW1lZCh0aGlzKTtcbn07XG5cbkVudGl0eS5wcm90b3R5cGUuX2dldERlY29kZXIgPSBmdW5jdGlvbiBfZ2V0RGVjb2RlcihlbmMpIHtcbiAgLy8gTGF6aWx5IGNyZWF0ZSBkZWNvZGVyXG4gIGlmICghdGhpcy5kZWNvZGVycy5oYXNPd25Qcm9wZXJ0eShlbmMpKVxuICAgIHRoaXMuZGVjb2RlcnNbZW5jXSA9IHRoaXMuX2NyZWF0ZU5hbWVkKGFzbjEuZGVjb2RlcnNbZW5jXSk7XG4gIHJldHVybiB0aGlzLmRlY29kZXJzW2VuY107XG59O1xuXG5FbnRpdHkucHJvdG90eXBlLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShkYXRhLCBlbmMsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIHRoaXMuX2dldERlY29kZXIoZW5jKS5kZWNvZGUoZGF0YSwgb3B0aW9ucyk7XG59O1xuXG5FbnRpdHkucHJvdG90eXBlLl9nZXRFbmNvZGVyID0gZnVuY3Rpb24gX2dldEVuY29kZXIoZW5jKSB7XG4gIC8vIExhemlseSBjcmVhdGUgZW5jb2RlclxuICBpZiAoIXRoaXMuZW5jb2RlcnMuaGFzT3duUHJvcGVydHkoZW5jKSlcbiAgICB0aGlzLmVuY29kZXJzW2VuY10gPSB0aGlzLl9jcmVhdGVOYW1lZChhc24xLmVuY29kZXJzW2VuY10pO1xuICByZXR1cm4gdGhpcy5lbmNvZGVyc1tlbmNdO1xufTtcblxuRW50aXR5LnByb3RvdHlwZS5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUoZGF0YSwgZW5jLCAvKiBpbnRlcm5hbCAqLyByZXBvcnRlcikge1xuICByZXR1cm4gdGhpcy5fZ2V0RW5jb2RlcihlbmMpLmVuY29kZShkYXRhLCByZXBvcnRlcik7XG59O1xuIiwidmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbnZhciBSZXBvcnRlciA9IHJlcXVpcmUoJy4uL2Jhc2UnKS5SZXBvcnRlcjtcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG5cbmZ1bmN0aW9uIERlY29kZXJCdWZmZXIoYmFzZSwgb3B0aW9ucykge1xuICBSZXBvcnRlci5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihiYXNlKSkge1xuICAgIHRoaXMuZXJyb3IoJ0lucHV0IG5vdCBCdWZmZXInKTtcbiAgICByZXR1cm47XG4gIH1cblxuICB0aGlzLmJhc2UgPSBiYXNlO1xuICB0aGlzLm9mZnNldCA9IDA7XG4gIHRoaXMubGVuZ3RoID0gYmFzZS5sZW5ndGg7XG59XG5pbmhlcml0cyhEZWNvZGVyQnVmZmVyLCBSZXBvcnRlcik7XG5leHBvcnRzLkRlY29kZXJCdWZmZXIgPSBEZWNvZGVyQnVmZmVyO1xuXG5EZWNvZGVyQnVmZmVyLnByb3RvdHlwZS5zYXZlID0gZnVuY3Rpb24gc2F2ZSgpIHtcbiAgcmV0dXJuIHsgb2Zmc2V0OiB0aGlzLm9mZnNldCwgcmVwb3J0ZXI6IFJlcG9ydGVyLnByb3RvdHlwZS5zYXZlLmNhbGwodGhpcykgfTtcbn07XG5cbkRlY29kZXJCdWZmZXIucHJvdG90eXBlLnJlc3RvcmUgPSBmdW5jdGlvbiByZXN0b3JlKHNhdmUpIHtcbiAgLy8gUmV0dXJuIHNraXBwZWQgZGF0YVxuICB2YXIgcmVzID0gbmV3IERlY29kZXJCdWZmZXIodGhpcy5iYXNlKTtcbiAgcmVzLm9mZnNldCA9IHNhdmUub2Zmc2V0O1xuICByZXMubGVuZ3RoID0gdGhpcy5vZmZzZXQ7XG5cbiAgdGhpcy5vZmZzZXQgPSBzYXZlLm9mZnNldDtcbiAgUmVwb3J0ZXIucHJvdG90eXBlLnJlc3RvcmUuY2FsbCh0aGlzLCBzYXZlLnJlcG9ydGVyKTtcblxuICByZXR1cm4gcmVzO1xufTtcblxuRGVjb2RlckJ1ZmZlci5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uIGlzRW1wdHkoKSB7XG4gIHJldHVybiB0aGlzLm9mZnNldCA9PT0gdGhpcy5sZW5ndGg7XG59O1xuXG5EZWNvZGVyQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbiByZWFkVUludDgoZmFpbCkge1xuICBpZiAodGhpcy5vZmZzZXQgKyAxIDw9IHRoaXMubGVuZ3RoKVxuICAgIHJldHVybiB0aGlzLmJhc2UucmVhZFVJbnQ4KHRoaXMub2Zmc2V0KyssIHRydWUpO1xuICBlbHNlXG4gICAgcmV0dXJuIHRoaXMuZXJyb3IoZmFpbCB8fCAnRGVjb2RlckJ1ZmZlciBvdmVycnVuJyk7XG59XG5cbkRlY29kZXJCdWZmZXIucHJvdG90eXBlLnNraXAgPSBmdW5jdGlvbiBza2lwKGJ5dGVzLCBmYWlsKSB7XG4gIGlmICghKHRoaXMub2Zmc2V0ICsgYnl0ZXMgPD0gdGhpcy5sZW5ndGgpKVxuICAgIHJldHVybiB0aGlzLmVycm9yKGZhaWwgfHwgJ0RlY29kZXJCdWZmZXIgb3ZlcnJ1bicpO1xuXG4gIHZhciByZXMgPSBuZXcgRGVjb2RlckJ1ZmZlcih0aGlzLmJhc2UpO1xuXG4gIC8vIFNoYXJlIHJlcG9ydGVyIHN0YXRlXG4gIHJlcy5fcmVwb3J0ZXJTdGF0ZSA9IHRoaXMuX3JlcG9ydGVyU3RhdGU7XG5cbiAgcmVzLm9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICByZXMubGVuZ3RoID0gdGhpcy5vZmZzZXQgKyBieXRlcztcbiAgdGhpcy5vZmZzZXQgKz0gYnl0ZXM7XG4gIHJldHVybiByZXM7XG59XG5cbkRlY29kZXJCdWZmZXIucHJvdG90eXBlLnJhdyA9IGZ1bmN0aW9uIHJhdyhzYXZlKSB7XG4gIHJldHVybiB0aGlzLmJhc2Uuc2xpY2Uoc2F2ZSA/IHNhdmUub2Zmc2V0IDogdGhpcy5vZmZzZXQsIHRoaXMubGVuZ3RoKTtcbn1cblxuZnVuY3Rpb24gRW5jb2RlckJ1ZmZlcih2YWx1ZSwgcmVwb3J0ZXIpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgdGhpcy5sZW5ndGggPSAwO1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZS5tYXAoZnVuY3Rpb24oaXRlbSkge1xuICAgICAgaWYgKCEoaXRlbSBpbnN0YW5jZW9mIEVuY29kZXJCdWZmZXIpKVxuICAgICAgICBpdGVtID0gbmV3IEVuY29kZXJCdWZmZXIoaXRlbSwgcmVwb3J0ZXIpO1xuICAgICAgdGhpcy5sZW5ndGggKz0gaXRlbS5sZW5ndGg7XG4gICAgICByZXR1cm4gaXRlbTtcbiAgICB9LCB0aGlzKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgaWYgKCEoMCA8PSB2YWx1ZSAmJiB2YWx1ZSA8PSAweGZmKSlcbiAgICAgIHJldHVybiByZXBvcnRlci5lcnJvcignbm9uLWJ5dGUgRW5jb2RlckJ1ZmZlciB2YWx1ZScpO1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLmxlbmd0aCA9IDE7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLmxlbmd0aCA9IEJ1ZmZlci5ieXRlTGVuZ3RoKHZhbHVlKTtcbiAgfSBlbHNlIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsdWUpKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIHRoaXMubGVuZ3RoID0gdmFsdWUubGVuZ3RoO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiByZXBvcnRlci5lcnJvcignVW5zdXBwb3J0ZWQgdHlwZTogJyArIHR5cGVvZiB2YWx1ZSk7XG4gIH1cbn1cbmV4cG9ydHMuRW5jb2RlckJ1ZmZlciA9IEVuY29kZXJCdWZmZXI7XG5cbkVuY29kZXJCdWZmZXIucHJvdG90eXBlLmpvaW4gPSBmdW5jdGlvbiBqb2luKG91dCwgb2Zmc2V0KSB7XG4gIGlmICghb3V0KVxuICAgIG91dCA9IG5ldyBCdWZmZXIodGhpcy5sZW5ndGgpO1xuICBpZiAoIW9mZnNldClcbiAgICBvZmZzZXQgPSAwO1xuXG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMClcbiAgICByZXR1cm4gb3V0O1xuXG4gIGlmIChBcnJheS5pc0FycmF5KHRoaXMudmFsdWUpKSB7XG4gICAgdGhpcy52YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uKGl0ZW0pIHtcbiAgICAgIGl0ZW0uam9pbihvdXQsIG9mZnNldCk7XG4gICAgICBvZmZzZXQgKz0gaXRlbS5sZW5ndGg7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLnZhbHVlID09PSAnbnVtYmVyJylcbiAgICAgIG91dFtvZmZzZXRdID0gdGhpcy52YWx1ZTtcbiAgICBlbHNlIGlmICh0eXBlb2YgdGhpcy52YWx1ZSA9PT0gJ3N0cmluZycpXG4gICAgICBvdXQud3JpdGUodGhpcy52YWx1ZSwgb2Zmc2V0KTtcbiAgICBlbHNlIGlmIChCdWZmZXIuaXNCdWZmZXIodGhpcy52YWx1ZSkpXG4gICAgICB0aGlzLnZhbHVlLmNvcHkob3V0LCBvZmZzZXQpO1xuICAgIG9mZnNldCArPSB0aGlzLmxlbmd0aDtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59O1xuIiwidmFyIGJhc2UgPSBleHBvcnRzO1xuXG5iYXNlLlJlcG9ydGVyID0gcmVxdWlyZSgnLi9yZXBvcnRlcicpLlJlcG9ydGVyO1xuYmFzZS5EZWNvZGVyQnVmZmVyID0gcmVxdWlyZSgnLi9idWZmZXInKS5EZWNvZGVyQnVmZmVyO1xuYmFzZS5FbmNvZGVyQnVmZmVyID0gcmVxdWlyZSgnLi9idWZmZXInKS5FbmNvZGVyQnVmZmVyO1xuYmFzZS5Ob2RlID0gcmVxdWlyZSgnLi9ub2RlJyk7XG4iLCJ2YXIgUmVwb3J0ZXIgPSByZXF1aXJlKCcuLi9iYXNlJykuUmVwb3J0ZXI7XG52YXIgRW5jb2RlckJ1ZmZlciA9IHJlcXVpcmUoJy4uL2Jhc2UnKS5FbmNvZGVyQnVmZmVyO1xudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcblxuLy8gU3VwcG9ydGVkIHRhZ3NcbnZhciB0YWdzID0gW1xuICAnc2VxJywgJ3NlcW9mJywgJ3NldCcsICdzZXRvZicsICdvY3RzdHInLCAnYml0c3RyJywgJ29iamlkJywgJ2Jvb2wnLFxuICAnZ2VudGltZScsICd1dGN0aW1lJywgJ251bGxfJywgJ2VudW0nLCAnaW50JywgJ2lhNXN0cicsICd1dGY4c3RyJywgJ2JtcHN0cicsXG4gICdudW1zdHInLCAncHJpbnRzdHInXG5dO1xuXG4vLyBQdWJsaWMgbWV0aG9kcyBsaXN0XG52YXIgbWV0aG9kcyA9IFtcbiAgJ2tleScsICdvYmonLCAndXNlJywgJ29wdGlvbmFsJywgJ2V4cGxpY2l0JywgJ2ltcGxpY2l0JywgJ2RlZicsICdjaG9pY2UnLFxuICAnYW55J1xuXS5jb25jYXQodGFncyk7XG5cbi8vIE92ZXJyaWRlZCBtZXRob2RzIGxpc3RcbnZhciBvdmVycmlkZWQgPSBbXG4gICdfcGVla1RhZycsICdfZGVjb2RlVGFnJywgJ191c2UnLFxuICAnX2RlY29kZVN0cicsICdfZGVjb2RlT2JqaWQnLCAnX2RlY29kZVRpbWUnLFxuICAnX2RlY29kZU51bGwnLCAnX2RlY29kZUludCcsICdfZGVjb2RlQm9vbCcsICdfZGVjb2RlTGlzdCcsXG5cbiAgJ19lbmNvZGVDb21wb3NpdGUnLCAnX2VuY29kZVN0cicsICdfZW5jb2RlT2JqaWQnLCAnX2VuY29kZVRpbWUnLFxuICAnX2VuY29kZU51bGwnLCAnX2VuY29kZUludCcsICdfZW5jb2RlQm9vbCdcbl07XG5cbmZ1bmN0aW9uIE5vZGUoZW5jLCBwYXJlbnQpIHtcbiAgdmFyIHN0YXRlID0ge307XG4gIHRoaXMuX2Jhc2VTdGF0ZSA9IHN0YXRlO1xuXG4gIHN0YXRlLmVuYyA9IGVuYztcblxuICBzdGF0ZS5wYXJlbnQgPSBwYXJlbnQgfHwgbnVsbDtcbiAgc3RhdGUuY2hpbGRyZW4gPSBudWxsO1xuXG4gIC8vIFN0YXRlXG4gIHN0YXRlLnRhZyA9IG51bGw7XG4gIHN0YXRlLmFyZ3MgPSBudWxsO1xuICBzdGF0ZS5yZXZlcnNlQXJncyA9IG51bGw7XG4gIHN0YXRlLmNob2ljZSA9IG51bGw7XG4gIHN0YXRlLm9wdGlvbmFsID0gZmFsc2U7XG4gIHN0YXRlLmFueSA9IGZhbHNlO1xuICBzdGF0ZS5vYmogPSBmYWxzZTtcbiAgc3RhdGUudXNlID0gbnVsbDtcbiAgc3RhdGUudXNlRGVjb2RlciA9IG51bGw7XG4gIHN0YXRlLmtleSA9IG51bGw7XG4gIHN0YXRlWydkZWZhdWx0J10gPSBudWxsO1xuICBzdGF0ZS5leHBsaWNpdCA9IG51bGw7XG4gIHN0YXRlLmltcGxpY2l0ID0gbnVsbDtcblxuICAvLyBTaG91bGQgY3JlYXRlIG5ldyBpbnN0YW5jZSBvbiBlYWNoIG1ldGhvZFxuICBpZiAoIXN0YXRlLnBhcmVudCkge1xuICAgIHN0YXRlLmNoaWxkcmVuID0gW107XG4gICAgdGhpcy5fd3JhcCgpO1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IE5vZGU7XG5cbnZhciBzdGF0ZVByb3BzID0gW1xuICAnZW5jJywgJ3BhcmVudCcsICdjaGlsZHJlbicsICd0YWcnLCAnYXJncycsICdyZXZlcnNlQXJncycsICdjaG9pY2UnLFxuICAnb3B0aW9uYWwnLCAnYW55JywgJ29iaicsICd1c2UnLCAnYWx0ZXJlZFVzZScsICdrZXknLCAnZGVmYXVsdCcsICdleHBsaWNpdCcsXG4gICdpbXBsaWNpdCdcbl07XG5cbk5vZGUucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gY2xvbmUoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgdmFyIGNzdGF0ZSA9IHt9O1xuICBzdGF0ZVByb3BzLmZvckVhY2goZnVuY3Rpb24ocHJvcCkge1xuICAgIGNzdGF0ZVtwcm9wXSA9IHN0YXRlW3Byb3BdO1xuICB9KTtcbiAgdmFyIHJlcyA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKGNzdGF0ZS5wYXJlbnQpO1xuICByZXMuX2Jhc2VTdGF0ZSA9IGNzdGF0ZTtcbiAgcmV0dXJuIHJlcztcbn07XG5cbk5vZGUucHJvdG90eXBlLl93cmFwID0gZnVuY3Rpb24gd3JhcCgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuICBtZXRob2RzLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgdGhpc1ttZXRob2RdID0gZnVuY3Rpb24gX3dyYXBwZWRNZXRob2QoKSB7XG4gICAgICB2YXIgY2xvbmUgPSBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgIHN0YXRlLmNoaWxkcmVuLnB1c2goY2xvbmUpO1xuICAgICAgcmV0dXJuIGNsb25lW21ldGhvZF0uYXBwbHkoY2xvbmUsIGFyZ3VtZW50cyk7XG4gICAgfTtcbiAgfSwgdGhpcyk7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uIGluaXQoYm9keSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlLnBhcmVudCA9PT0gbnVsbCk7XG4gIGJvZHkuY2FsbCh0aGlzKTtcblxuICAvLyBGaWx0ZXIgY2hpbGRyZW5cbiAgc3RhdGUuY2hpbGRyZW4gPSBzdGF0ZS5jaGlsZHJlbi5maWx0ZXIoZnVuY3Rpb24oY2hpbGQpIHtcbiAgICByZXR1cm4gY2hpbGQuX2Jhc2VTdGF0ZS5wYXJlbnQgPT09IHRoaXM7XG4gIH0sIHRoaXMpO1xuICBhc3NlcnQuZXF1YWwoc3RhdGUuY2hpbGRyZW4ubGVuZ3RoLCAxLCAnUm9vdCBub2RlIGNhbiBoYXZlIG9ubHkgb25lIGNoaWxkJyk7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5fdXNlQXJncyA9IGZ1bmN0aW9uIHVzZUFyZ3MoYXJncykge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgLy8gRmlsdGVyIGNoaWxkcmVuIGFuZCBhcmdzXG4gIHZhciBjaGlsZHJlbiA9IGFyZ3MuZmlsdGVyKGZ1bmN0aW9uKGFyZykge1xuICAgIHJldHVybiBhcmcgaW5zdGFuY2VvZiB0aGlzLmNvbnN0cnVjdG9yO1xuICB9LCB0aGlzKTtcbiAgYXJncyA9IGFyZ3MuZmlsdGVyKGZ1bmN0aW9uKGFyZykge1xuICAgIHJldHVybiAhKGFyZyBpbnN0YW5jZW9mIHRoaXMuY29uc3RydWN0b3IpO1xuICB9LCB0aGlzKTtcblxuICBpZiAoY2hpbGRyZW4ubGVuZ3RoICE9PSAwKSB7XG4gICAgYXNzZXJ0KHN0YXRlLmNoaWxkcmVuID09PSBudWxsKTtcbiAgICBzdGF0ZS5jaGlsZHJlbiA9IGNoaWxkcmVuO1xuXG4gICAgLy8gUmVwbGFjZSBwYXJlbnQgdG8gbWFpbnRhaW4gYmFja3dhcmQgbGlua1xuICAgIGNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24oY2hpbGQpIHtcbiAgICAgIGNoaWxkLl9iYXNlU3RhdGUucGFyZW50ID0gdGhpcztcbiAgICB9LCB0aGlzKTtcbiAgfVxuICBpZiAoYXJncy5sZW5ndGggIT09IDApIHtcbiAgICBhc3NlcnQoc3RhdGUuYXJncyA9PT0gbnVsbCk7XG4gICAgc3RhdGUuYXJncyA9IGFyZ3M7XG4gICAgc3RhdGUucmV2ZXJzZUFyZ3MgPSBhcmdzLm1hcChmdW5jdGlvbihhcmcpIHtcbiAgICAgIGlmICh0eXBlb2YgYXJnICE9PSAnb2JqZWN0JyB8fCBhcmcuY29uc3RydWN0b3IgIT09IE9iamVjdClcbiAgICAgICAgcmV0dXJuIGFyZztcblxuICAgICAgdmFyIHJlcyA9IHt9O1xuICAgICAgT2JqZWN0LmtleXMoYXJnKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBpZiAoa2V5ID09IChrZXkgfCAwKSlcbiAgICAgICAgICBrZXkgfD0gMDtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJnW2tleV07XG4gICAgICAgIHJlc1t2YWx1ZV0gPSBrZXk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXM7XG4gICAgfSk7XG4gIH1cbn07XG5cbi8vXG4vLyBPdmVycmlkZWQgbWV0aG9kc1xuLy9cblxub3ZlcnJpZGVkLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gIE5vZGUucHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbiBfb3ZlcnJpZGVkKCkge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgICB0aHJvdyBuZXcgRXJyb3IobWV0aG9kICsgJyBub3QgaW1wbGVtZW50ZWQgZm9yIGVuY29kaW5nOiAnICsgc3RhdGUuZW5jKTtcbiAgfTtcbn0pO1xuXG4vL1xuLy8gUHVibGljIG1ldGhvZHNcbi8vXG5cbnRhZ3MuZm9yRWFjaChmdW5jdGlvbih0YWcpIHtcbiAgTm9kZS5wcm90b3R5cGVbdGFnXSA9IGZ1bmN0aW9uIF90YWdNZXRob2QoKSB7XG4gICAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblxuICAgIGFzc2VydChzdGF0ZS50YWcgPT09IG51bGwpO1xuICAgIHN0YXRlLnRhZyA9IHRhZztcblxuICAgIHRoaXMuX3VzZUFyZ3MoYXJncyk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcbn0pO1xuXG5Ob2RlLnByb3RvdHlwZS51c2UgPSBmdW5jdGlvbiB1c2UoaXRlbSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlLnVzZSA9PT0gbnVsbCk7XG4gIHN0YXRlLnVzZSA9IGl0ZW07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5vcHRpb25hbCA9IGZ1bmN0aW9uIG9wdGlvbmFsKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgc3RhdGUub3B0aW9uYWwgPSB0cnVlO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuTm9kZS5wcm90b3R5cGUuZGVmID0gZnVuY3Rpb24gZGVmKHZhbCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlWydkZWZhdWx0J10gPT09IG51bGwpO1xuICBzdGF0ZVsnZGVmYXVsdCddID0gdmFsO1xuICBzdGF0ZS5vcHRpb25hbCA9IHRydWU7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5leHBsaWNpdCA9IGZ1bmN0aW9uIGV4cGxpY2l0KG51bSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlLmV4cGxpY2l0ID09PSBudWxsICYmIHN0YXRlLmltcGxpY2l0ID09PSBudWxsKTtcbiAgc3RhdGUuZXhwbGljaXQgPSBudW07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5pbXBsaWNpdCA9IGZ1bmN0aW9uIGltcGxpY2l0KG51bSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlLmV4cGxpY2l0ID09PSBudWxsICYmIHN0YXRlLmltcGxpY2l0ID09PSBudWxsKTtcbiAgc3RhdGUuaW1wbGljaXQgPSBudW07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5vYmogPSBmdW5jdGlvbiBvYmooKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuXG4gIHN0YXRlLm9iaiA9IHRydWU7XG5cbiAgaWYgKGFyZ3MubGVuZ3RoICE9PSAwKVxuICAgIHRoaXMuX3VzZUFyZ3MoYXJncyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5rZXkgPSBmdW5jdGlvbiBrZXkobmV3S2V5KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICBhc3NlcnQoc3RhdGUua2V5ID09PSBudWxsKTtcbiAgc3RhdGUua2V5ID0gbmV3S2V5O1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuTm9kZS5wcm90b3R5cGUuYW55ID0gZnVuY3Rpb24gYW55KCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgc3RhdGUuYW55ID0gdHJ1ZTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbk5vZGUucHJvdG90eXBlLmNob2ljZSA9IGZ1bmN0aW9uIGNob2ljZShvYmopIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIGFzc2VydChzdGF0ZS5jaG9pY2UgPT09IG51bGwpO1xuICBzdGF0ZS5jaG9pY2UgPSBvYmo7XG4gIHRoaXMuX3VzZUFyZ3MoT2JqZWN0LmtleXMob2JqKS5tYXAoZnVuY3Rpb24oa2V5KSB7XG4gICAgcmV0dXJuIG9ialtrZXldO1xuICB9KSk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vL1xuLy8gRGVjb2Rpbmdcbi8vXG5cbk5vZGUucHJvdG90eXBlLl9kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUoaW5wdXQpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIC8vIERlY29kZSByb290IG5vZGVcbiAgaWYgKHN0YXRlLnBhcmVudCA9PT0gbnVsbClcbiAgICByZXR1cm4gaW5wdXQud3JhcFJlc3VsdChzdGF0ZS5jaGlsZHJlblswXS5fZGVjb2RlKGlucHV0KSk7XG5cbiAgdmFyIHJlc3VsdCA9IHN0YXRlWydkZWZhdWx0J107XG4gIHZhciBwcmVzZW50ID0gdHJ1ZTtcblxuICB2YXIgcHJldktleTtcbiAgaWYgKHN0YXRlLmtleSAhPT0gbnVsbClcbiAgICBwcmV2S2V5ID0gaW5wdXQuZW50ZXJLZXkoc3RhdGUua2V5KTtcblxuICAvLyBDaGVjayBpZiB0YWcgaXMgdGhlcmVcbiAgaWYgKHN0YXRlLm9wdGlvbmFsKSB7XG4gICAgdmFyIHRhZyA9IG51bGw7XG4gICAgaWYgKHN0YXRlLmV4cGxpY2l0ICE9PSBudWxsKVxuICAgICAgdGFnID0gc3RhdGUuZXhwbGljaXQ7XG4gICAgZWxzZSBpZiAoc3RhdGUuaW1wbGljaXQgIT09IG51bGwpXG4gICAgICB0YWcgPSBzdGF0ZS5pbXBsaWNpdDtcbiAgICBlbHNlIGlmIChzdGF0ZS50YWcgIT09IG51bGwpXG4gICAgICB0YWcgPSBzdGF0ZS50YWc7XG5cbiAgICBpZiAodGFnID09PSBudWxsICYmICFzdGF0ZS5hbnkpIHtcbiAgICAgIC8vIFRyaWFsIGFuZCBFcnJvclxuICAgICAgdmFyIHNhdmUgPSBpbnB1dC5zYXZlKCk7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoc3RhdGUuY2hvaWNlID09PSBudWxsKVxuICAgICAgICAgIHRoaXMuX2RlY29kZUdlbmVyaWMoc3RhdGUudGFnLCBpbnB1dCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICB0aGlzLl9kZWNvZGVDaG9pY2UoaW5wdXQpO1xuICAgICAgICBwcmVzZW50ID0gdHJ1ZTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcHJlc2VudCA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgaW5wdXQucmVzdG9yZShzYXZlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJlc2VudCA9IHRoaXMuX3BlZWtUYWcoaW5wdXQsIHRhZywgc3RhdGUuYW55KTtcblxuICAgICAgaWYgKGlucHV0LmlzRXJyb3IocHJlc2VudCkpXG4gICAgICAgIHJldHVybiBwcmVzZW50O1xuICAgIH1cbiAgfVxuXG4gIC8vIFB1c2ggb2JqZWN0IG9uIHN0YWNrXG4gIHZhciBwcmV2T2JqO1xuICBpZiAoc3RhdGUub2JqICYmIHByZXNlbnQpXG4gICAgcHJldk9iaiA9IGlucHV0LmVudGVyT2JqZWN0KCk7XG5cbiAgaWYgKHByZXNlbnQpIHtcbiAgICAvLyBVbndyYXAgZXhwbGljaXQgdmFsdWVzXG4gICAgaWYgKHN0YXRlLmV4cGxpY2l0ICE9PSBudWxsKSB7XG4gICAgICB2YXIgZXhwbGljaXQgPSB0aGlzLl9kZWNvZGVUYWcoaW5wdXQsIHN0YXRlLmV4cGxpY2l0KTtcbiAgICAgIGlmIChpbnB1dC5pc0Vycm9yKGV4cGxpY2l0KSlcbiAgICAgICAgcmV0dXJuIGV4cGxpY2l0O1xuICAgICAgaW5wdXQgPSBleHBsaWNpdDtcbiAgICB9XG5cbiAgICAvLyBVbndyYXAgaW1wbGljaXQgYW5kIG5vcm1hbCB2YWx1ZXNcbiAgICBpZiAoc3RhdGUudXNlID09PSBudWxsICYmIHN0YXRlLmNob2ljZSA9PT0gbnVsbCkge1xuICAgICAgaWYgKHN0YXRlLmFueSlcbiAgICAgICAgdmFyIHNhdmUgPSBpbnB1dC5zYXZlKCk7XG4gICAgICB2YXIgYm9keSA9IHRoaXMuX2RlY29kZVRhZyhcbiAgICAgICAgaW5wdXQsXG4gICAgICAgIHN0YXRlLmltcGxpY2l0ICE9PSBudWxsID8gc3RhdGUuaW1wbGljaXQgOiBzdGF0ZS50YWcsXG4gICAgICAgIHN0YXRlLmFueVxuICAgICAgKTtcbiAgICAgIGlmIChpbnB1dC5pc0Vycm9yKGJvZHkpKVxuICAgICAgICByZXR1cm4gYm9keTtcblxuICAgICAgaWYgKHN0YXRlLmFueSlcbiAgICAgICAgcmVzdWx0ID0gaW5wdXQucmF3KHNhdmUpO1xuICAgICAgZWxzZVxuICAgICAgICBpbnB1dCA9IGJvZHk7XG4gICAgfVxuXG4gICAgLy8gU2VsZWN0IHByb3BlciBtZXRob2QgZm9yIHRhZ1xuICAgIGlmIChzdGF0ZS5hbnkpXG4gICAgICByZXN1bHQgPSByZXN1bHQ7XG4gICAgZWxzZSBpZiAoc3RhdGUuY2hvaWNlID09PSBudWxsKVxuICAgICAgcmVzdWx0ID0gdGhpcy5fZGVjb2RlR2VuZXJpYyhzdGF0ZS50YWcsIGlucHV0KTtcbiAgICBlbHNlXG4gICAgICByZXN1bHQgPSB0aGlzLl9kZWNvZGVDaG9pY2UoaW5wdXQpO1xuXG4gICAgaWYgKGlucHV0LmlzRXJyb3IocmVzdWx0KSlcbiAgICAgIHJldHVybiByZXN1bHQ7XG5cbiAgICAvLyBEZWNvZGUgY2hpbGRyZW5cbiAgICBpZiAoIXN0YXRlLmFueSAmJiBzdGF0ZS5jaG9pY2UgPT09IG51bGwgJiYgc3RhdGUuY2hpbGRyZW4gIT09IG51bGwpIHtcbiAgICAgIHZhciBmYWlsID0gc3RhdGUuY2hpbGRyZW4uc29tZShmdW5jdGlvbiBkZWNvZGVDaGlsZHJlbihjaGlsZCkge1xuICAgICAgICAvLyBOT1RFOiBXZSBhcmUgaWdub3JpbmcgZXJyb3JzIGhlcmUsIHRvIGxldCBwYXJzZXIgY29udGludWUgd2l0aCBvdGhlclxuICAgICAgICAvLyBwYXJ0cyBvZiBlbmNvZGVkIGRhdGFcbiAgICAgICAgY2hpbGQuX2RlY29kZShpbnB1dCk7XG4gICAgICB9KTtcbiAgICAgIGlmIChmYWlsKVxuICAgICAgICByZXR1cm4gZXJyO1xuICAgIH1cbiAgfVxuXG4gIC8vIFBvcCBvYmplY3RcbiAgaWYgKHN0YXRlLm9iaiAmJiBwcmVzZW50KVxuICAgIHJlc3VsdCA9IGlucHV0LmxlYXZlT2JqZWN0KHByZXZPYmopO1xuXG4gIC8vIFNldCBrZXlcbiAgaWYgKHN0YXRlLmtleSAhPT0gbnVsbCAmJiAocmVzdWx0ICE9PSBudWxsIHx8IHByZXNlbnQgPT09IHRydWUpKVxuICAgIGlucHV0LmxlYXZlS2V5KHByZXZLZXksIHN0YXRlLmtleSwgcmVzdWx0KTtcblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuTm9kZS5wcm90b3R5cGUuX2RlY29kZUdlbmVyaWMgPSBmdW5jdGlvbiBkZWNvZGVHZW5lcmljKHRhZywgaW5wdXQpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIGlmICh0YWcgPT09ICdzZXEnIHx8IHRhZyA9PT0gJ3NldCcpXG4gICAgcmV0dXJuIG51bGw7XG4gIGlmICh0YWcgPT09ICdzZXFvZicgfHwgdGFnID09PSAnc2V0b2YnKVxuICAgIHJldHVybiB0aGlzLl9kZWNvZGVMaXN0KGlucHV0LCB0YWcsIHN0YXRlLmFyZ3NbMF0pO1xuICBlbHNlIGlmICh0YWcgPT09ICdvY3RzdHInIHx8IHRhZyA9PT0gJ2JpdHN0cicpXG4gICAgcmV0dXJuIHRoaXMuX2RlY29kZVN0cihpbnB1dCwgdGFnKTtcbiAgZWxzZSBpZiAodGFnID09PSAnaWE1c3RyJyB8fCB0YWcgPT09ICd1dGY4c3RyJyB8fCB0YWcgPT09ICdibXBzdHInKVxuICAgIHJldHVybiB0aGlzLl9kZWNvZGVTdHIoaW5wdXQsIHRhZyk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ251bXN0cicgfHwgdGFnID09PSAncHJpbnRzdHInKVxuICAgIHJldHVybiB0aGlzLl9kZWNvZGVTdHIoaW5wdXQsIHRhZyk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ29iamlkJyAmJiBzdGF0ZS5hcmdzKVxuICAgIHJldHVybiB0aGlzLl9kZWNvZGVPYmppZChpbnB1dCwgc3RhdGUuYXJnc1swXSwgc3RhdGUuYXJnc1sxXSk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ29iamlkJylcbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlT2JqaWQoaW5wdXQsIG51bGwsIG51bGwpO1xuICBlbHNlIGlmICh0YWcgPT09ICdnZW50aW1lJyB8fCB0YWcgPT09ICd1dGN0aW1lJylcbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlVGltZShpbnB1dCwgdGFnKTtcbiAgZWxzZSBpZiAodGFnID09PSAnbnVsbF8nKVxuICAgIHJldHVybiB0aGlzLl9kZWNvZGVOdWxsKGlucHV0KTtcbiAgZWxzZSBpZiAodGFnID09PSAnYm9vbCcpXG4gICAgcmV0dXJuIHRoaXMuX2RlY29kZUJvb2woaW5wdXQpO1xuICBlbHNlIGlmICh0YWcgPT09ICdpbnQnIHx8IHRhZyA9PT0gJ2VudW0nKVxuICAgIHJldHVybiB0aGlzLl9kZWNvZGVJbnQoaW5wdXQsIHN0YXRlLmFyZ3MgJiYgc3RhdGUuYXJnc1swXSk7XG4gIGVsc2UgaWYgKHN0YXRlLnVzZSAhPT0gbnVsbClcbiAgICByZXR1cm4gdGhpcy5fZ2V0VXNlKHN0YXRlLnVzZSwgaW5wdXQuX3JlcG9ydGVyU3RhdGUub2JqKS5fZGVjb2RlKGlucHV0KTtcbiAgZWxzZVxuICAgIHJldHVybiBpbnB1dC5lcnJvcigndW5rbm93biB0YWc6ICcgKyB0YWcpO1xuXG4gIHJldHVybiBudWxsO1xufTtcblxuTm9kZS5wcm90b3R5cGUuX2dldFVzZSA9IGZ1bmN0aW9uIF9nZXRVc2UoZW50aXR5LCBvYmopIHtcblxuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG4gIC8vIENyZWF0ZSBhbHRlcmVkIHVzZSBkZWNvZGVyIGlmIGltcGxpY2l0IGlzIHNldFxuICBzdGF0ZS51c2VEZWNvZGVyID0gdGhpcy5fdXNlKGVudGl0eSwgb2JqKTtcbiAgYXNzZXJ0KHN0YXRlLnVzZURlY29kZXIuX2Jhc2VTdGF0ZS5wYXJlbnQgPT09IG51bGwpO1xuICBzdGF0ZS51c2VEZWNvZGVyID0gc3RhdGUudXNlRGVjb2Rlci5fYmFzZVN0YXRlLmNoaWxkcmVuWzBdO1xuICBpZiAoc3RhdGUuaW1wbGljaXQgIT09IHN0YXRlLnVzZURlY29kZXIuX2Jhc2VTdGF0ZS5pbXBsaWNpdCkge1xuICAgIHN0YXRlLnVzZURlY29kZXIgPSBzdGF0ZS51c2VEZWNvZGVyLmNsb25lKCk7XG4gICAgc3RhdGUudXNlRGVjb2Rlci5fYmFzZVN0YXRlLmltcGxpY2l0ID0gc3RhdGUuaW1wbGljaXQ7XG4gIH1cbiAgcmV0dXJuIHN0YXRlLnVzZURlY29kZXI7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5fZGVjb2RlQ2hvaWNlID0gZnVuY3Rpb24gZGVjb2RlQ2hvaWNlKGlucHV0KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgdmFyIHJlc3VsdCA9IG51bGw7XG4gIHZhciBtYXRjaCA9IGZhbHNlO1xuXG4gIE9iamVjdC5rZXlzKHN0YXRlLmNob2ljZSkuc29tZShmdW5jdGlvbihrZXkpIHtcbiAgICB2YXIgc2F2ZSA9IGlucHV0LnNhdmUoKTtcbiAgICB2YXIgbm9kZSA9IHN0YXRlLmNob2ljZVtrZXldO1xuICAgIHRyeSB7XG4gICAgICB2YXIgdmFsdWUgPSBub2RlLl9kZWNvZGUoaW5wdXQpO1xuICAgICAgaWYgKGlucHV0LmlzRXJyb3IodmFsdWUpKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICAgIHJlc3VsdCA9IHsgdHlwZToga2V5LCB2YWx1ZTogdmFsdWUgfTtcbiAgICAgIG1hdGNoID0gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpbnB1dC5yZXN0b3JlKHNhdmUpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSwgdGhpcyk7XG5cbiAgaWYgKCFtYXRjaClcbiAgICByZXR1cm4gaW5wdXQuZXJyb3IoJ0Nob2ljZSBub3QgbWF0Y2hlZCcpO1xuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG4vL1xuLy8gRW5jb2Rpbmdcbi8vXG5cbk5vZGUucHJvdG90eXBlLl9jcmVhdGVFbmNvZGVyQnVmZmVyID0gZnVuY3Rpb24gY3JlYXRlRW5jb2RlckJ1ZmZlcihkYXRhKSB7XG4gIHJldHVybiBuZXcgRW5jb2RlckJ1ZmZlcihkYXRhLCB0aGlzLnJlcG9ydGVyKTtcbn07XG5cbk5vZGUucHJvdG90eXBlLl9lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUoZGF0YSwgcmVwb3J0ZXIsIHBhcmVudCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG4gIGlmIChzdGF0ZVsnZGVmYXVsdCddICE9PSBudWxsICYmIHN0YXRlWydkZWZhdWx0J10gPT09IGRhdGEpXG4gICAgcmV0dXJuO1xuXG4gIHZhciByZXN1bHQgPSB0aGlzLl9lbmNvZGVWYWx1ZShkYXRhLCByZXBvcnRlciwgcGFyZW50KTtcbiAgaWYgKHJlc3VsdCA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybjtcblxuICBpZiAodGhpcy5fc2tpcERlZmF1bHQocmVzdWx0LCByZXBvcnRlciwgcGFyZW50KSlcbiAgICByZXR1cm47XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbk5vZGUucHJvdG90eXBlLl9lbmNvZGVWYWx1ZSA9IGZ1bmN0aW9uIGVuY29kZShkYXRhLCByZXBvcnRlciwgcGFyZW50KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICAvLyBEZWNvZGUgcm9vdCBub2RlXG4gIGlmIChzdGF0ZS5wYXJlbnQgPT09IG51bGwpXG4gICAgcmV0dXJuIHN0YXRlLmNoaWxkcmVuWzBdLl9lbmNvZGUoZGF0YSwgcmVwb3J0ZXIgfHwgbmV3IFJlcG9ydGVyKCkpO1xuXG4gIHZhciByZXN1bHQgPSBudWxsO1xuICB2YXIgcHJlc2VudCA9IHRydWU7XG5cbiAgLy8gU2V0IHJlcG9ydGVyIHRvIHNoYXJlIGl0IHdpdGggYSBjaGlsZCBjbGFzc1xuICB0aGlzLnJlcG9ydGVyID0gcmVwb3J0ZXI7XG5cbiAgLy8gQ2hlY2sgaWYgZGF0YSBpcyB0aGVyZVxuICBpZiAoc3RhdGUub3B0aW9uYWwgJiYgZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHN0YXRlWydkZWZhdWx0J10gIT09IG51bGwpXG4gICAgICBkYXRhID0gc3RhdGVbJ2RlZmF1bHQnXVxuICAgIGVsc2VcbiAgICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEZvciBlcnJvciByZXBvcnRpbmdcbiAgdmFyIHByZXZLZXk7XG5cbiAgLy8gRW5jb2RlIGNoaWxkcmVuIGZpcnN0XG4gIHZhciBjb250ZW50ID0gbnVsbDtcbiAgdmFyIHByaW1pdGl2ZSA9IGZhbHNlO1xuICBpZiAoc3RhdGUuYW55KSB7XG4gICAgLy8gQW55dGhpbmcgdGhhdCB3YXMgZ2l2ZW4gaXMgdHJhbnNsYXRlZCB0byBidWZmZXJcbiAgICByZXN1bHQgPSB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKGRhdGEpO1xuICB9IGVsc2UgaWYgKHN0YXRlLmNob2ljZSkge1xuICAgIHJlc3VsdCA9IHRoaXMuX2VuY29kZUNob2ljZShkYXRhLCByZXBvcnRlcik7XG4gIH0gZWxzZSBpZiAoc3RhdGUuY2hpbGRyZW4pIHtcbiAgICBjb250ZW50ID0gc3RhdGUuY2hpbGRyZW4ubWFwKGZ1bmN0aW9uKGNoaWxkKSB7XG4gICAgICBpZiAoY2hpbGQuX2Jhc2VTdGF0ZS50YWcgPT09ICdudWxsXycpXG4gICAgICAgIHJldHVybiBjaGlsZC5fZW5jb2RlKG51bGwsIHJlcG9ydGVyLCBkYXRhKTtcblxuICAgICAgaWYgKGNoaWxkLl9iYXNlU3RhdGUua2V5ID09PSBudWxsKVxuICAgICAgICByZXR1cm4gcmVwb3J0ZXIuZXJyb3IoJ0NoaWxkIHNob3VsZCBoYXZlIGEga2V5Jyk7XG4gICAgICB2YXIgcHJldktleSA9IHJlcG9ydGVyLmVudGVyS2V5KGNoaWxkLl9iYXNlU3RhdGUua2V5KTtcblxuICAgICAgaWYgKHR5cGVvZiBkYXRhICE9PSAnb2JqZWN0JylcbiAgICAgICAgcmV0dXJuIHJlcG9ydGVyLmVycm9yKCdDaGlsZCBleHBlY3RlZCwgYnV0IGlucHV0IGlzIG5vdCBvYmplY3QnKTtcblxuICAgICAgdmFyIHJlcyA9IGNoaWxkLl9lbmNvZGUoZGF0YVtjaGlsZC5fYmFzZVN0YXRlLmtleV0sIHJlcG9ydGVyLCBkYXRhKTtcbiAgICAgIHJlcG9ydGVyLmxlYXZlS2V5KHByZXZLZXkpO1xuXG4gICAgICByZXR1cm4gcmVzO1xuICAgIH0sIHRoaXMpLmZpbHRlcihmdW5jdGlvbihjaGlsZCkge1xuICAgICAgcmV0dXJuIGNoaWxkO1xuICAgIH0pO1xuXG4gICAgY29udGVudCA9IHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoY29udGVudCk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHN0YXRlLnRhZyA9PT0gJ3NlcW9mJyB8fCBzdGF0ZS50YWcgPT09ICdzZXRvZicpIHtcbiAgICAgIC8vIFRPRE8oaW5kdXRueSk6IHRoaXMgc2hvdWxkIGJlIHRocm93biBvbiBEU0wgbGV2ZWxcbiAgICAgIGlmICghKHN0YXRlLmFyZ3MgJiYgc3RhdGUuYXJncy5sZW5ndGggPT09IDEpKVxuICAgICAgICByZXR1cm4gcmVwb3J0ZXIuZXJyb3IoJ1RvbyBtYW55IGFyZ3MgZm9yIDogJyArIHN0YXRlLnRhZyk7XG5cbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShkYXRhKSlcbiAgICAgICAgcmV0dXJuIHJlcG9ydGVyLmVycm9yKCdzZXFvZi9zZXRvZiwgYnV0IGRhdGEgaXMgbm90IEFycmF5Jyk7XG5cbiAgICAgIHZhciBjaGlsZCA9IHRoaXMuY2xvbmUoKTtcbiAgICAgIGNoaWxkLl9iYXNlU3RhdGUuaW1wbGljaXQgPSBudWxsO1xuICAgICAgY29udGVudCA9IHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoZGF0YS5tYXAoZnVuY3Rpb24oaXRlbSkge1xuICAgICAgICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldFVzZShzdGF0ZS5hcmdzWzBdLCBkYXRhKS5fZW5jb2RlKGl0ZW0sIHJlcG9ydGVyKTtcbiAgICAgIH0sIGNoaWxkKSk7XG4gICAgfSBlbHNlIGlmIChzdGF0ZS51c2UgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCA9IHRoaXMuX2dldFVzZShzdGF0ZS51c2UsIHBhcmVudCkuX2VuY29kZShkYXRhLCByZXBvcnRlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnRlbnQgPSB0aGlzLl9lbmNvZGVQcmltaXRpdmUoc3RhdGUudGFnLCBkYXRhKTtcbiAgICAgIHByaW1pdGl2ZSA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgLy8gRW5jb2RlIGRhdGEgaXRzZWxmXG4gIHZhciByZXN1bHQ7XG4gIGlmICghc3RhdGUuYW55ICYmIHN0YXRlLmNob2ljZSA9PT0gbnVsbCkge1xuICAgIHZhciB0YWcgPSBzdGF0ZS5pbXBsaWNpdCAhPT0gbnVsbCA/IHN0YXRlLmltcGxpY2l0IDogc3RhdGUudGFnO1xuICAgIHZhciBjbHMgPSBzdGF0ZS5pbXBsaWNpdCA9PT0gbnVsbCA/ICd1bml2ZXJzYWwnIDogJ2NvbnRleHQnO1xuXG4gICAgaWYgKHRhZyA9PT0gbnVsbCkge1xuICAgICAgaWYgKHN0YXRlLnVzZSA9PT0gbnVsbClcbiAgICAgICAgcmVwb3J0ZXIuZXJyb3IoJ1RhZyBjb3VsZCBiZSBvbW1pdGVkIG9ubHkgZm9yIC51c2UoKScpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoc3RhdGUudXNlID09PSBudWxsKVxuICAgICAgICByZXN1bHQgPSB0aGlzLl9lbmNvZGVDb21wb3NpdGUodGFnLCBwcmltaXRpdmUsIGNscywgY29udGVudCk7XG4gICAgfVxuICB9XG5cbiAgLy8gV3JhcCBpbiBleHBsaWNpdFxuICBpZiAoc3RhdGUuZXhwbGljaXQgIT09IG51bGwpXG4gICAgcmVzdWx0ID0gdGhpcy5fZW5jb2RlQ29tcG9zaXRlKHN0YXRlLmV4cGxpY2l0LCBmYWxzZSwgJ2NvbnRleHQnLCByZXN1bHQpO1xuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5fZW5jb2RlQ2hvaWNlID0gZnVuY3Rpb24gZW5jb2RlQ2hvaWNlKGRhdGEsIHJlcG9ydGVyKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICB2YXIgbm9kZSA9IHN0YXRlLmNob2ljZVtkYXRhLnR5cGVdO1xuICBpZiAoIW5vZGUpIHtcbiAgICBhc3NlcnQoXG4gICAgICAgIGZhbHNlLFxuICAgICAgICBkYXRhLnR5cGUgKyAnIG5vdCBmb3VuZCBpbiAnICtcbiAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KE9iamVjdC5rZXlzKHN0YXRlLmNob2ljZSkpKTtcbiAgfVxuICByZXR1cm4gbm9kZS5fZW5jb2RlKGRhdGEudmFsdWUsIHJlcG9ydGVyKTtcbn07XG5cbk5vZGUucHJvdG90eXBlLl9lbmNvZGVQcmltaXRpdmUgPSBmdW5jdGlvbiBlbmNvZGVQcmltaXRpdmUodGFnLCBkYXRhKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICBpZiAodGFnID09PSAnb2N0c3RyJyB8fCB0YWcgPT09ICdiaXRzdHInIHx8IHRhZyA9PT0gJ2lhNXN0cicpXG4gICAgcmV0dXJuIHRoaXMuX2VuY29kZVN0cihkYXRhLCB0YWcpO1xuICBlbHNlIGlmICh0YWcgPT09ICd1dGY4c3RyJyB8fCB0YWcgPT09ICdibXBzdHInKVxuICAgIHJldHVybiB0aGlzLl9lbmNvZGVTdHIoZGF0YSwgdGFnKTtcbiAgZWxzZSBpZiAodGFnID09PSAnbnVtc3RyJyB8fCB0YWcgPT09ICdwcmludHN0cicpXG4gICAgcmV0dXJuIHRoaXMuX2VuY29kZVN0cihkYXRhLCB0YWcpO1xuICBlbHNlIGlmICh0YWcgPT09ICdvYmppZCcgJiYgc3RhdGUuYXJncylcbiAgICByZXR1cm4gdGhpcy5fZW5jb2RlT2JqaWQoZGF0YSwgc3RhdGUucmV2ZXJzZUFyZ3NbMF0sIHN0YXRlLmFyZ3NbMV0pO1xuICBlbHNlIGlmICh0YWcgPT09ICdvYmppZCcpXG4gICAgcmV0dXJuIHRoaXMuX2VuY29kZU9iamlkKGRhdGEsIG51bGwsIG51bGwpO1xuICBlbHNlIGlmICh0YWcgPT09ICdnZW50aW1lJyB8fCB0YWcgPT09ICd1dGN0aW1lJylcbiAgICByZXR1cm4gdGhpcy5fZW5jb2RlVGltZShkYXRhLCB0YWcpO1xuICBlbHNlIGlmICh0YWcgPT09ICdudWxsXycpXG4gICAgcmV0dXJuIHRoaXMuX2VuY29kZU51bGwoKTtcbiAgZWxzZSBpZiAodGFnID09PSAnaW50JyB8fCB0YWcgPT09ICdlbnVtJylcbiAgICByZXR1cm4gdGhpcy5fZW5jb2RlSW50KGRhdGEsIHN0YXRlLmFyZ3MgJiYgc3RhdGUucmV2ZXJzZUFyZ3NbMF0pO1xuICBlbHNlIGlmICh0YWcgPT09ICdib29sJylcbiAgICByZXR1cm4gdGhpcy5fZW5jb2RlQm9vbChkYXRhKTtcbiAgZWxzZVxuICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgdGFnOiAnICsgdGFnKTtcbn07XG5cbk5vZGUucHJvdG90eXBlLl9pc051bXN0ciA9IGZ1bmN0aW9uIGlzTnVtc3RyKHN0cikge1xuICByZXR1cm4gL15bMC05IF0qJC8udGVzdChzdHIpO1xufTtcblxuTm9kZS5wcm90b3R5cGUuX2lzUHJpbnRzdHIgPSBmdW5jdGlvbiBpc1ByaW50c3RyKHN0cikge1xuICByZXR1cm4gL15bQS1aYS16MC05ICdcXChcXClcXCssXFwtXFwuXFwvOj1cXD9dKiQvLnRlc3Qoc3RyKTtcbn07IiwidmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxuZnVuY3Rpb24gUmVwb3J0ZXIob3B0aW9ucykge1xuICB0aGlzLl9yZXBvcnRlclN0YXRlID0ge1xuICAgIG9iajogbnVsbCxcbiAgICBwYXRoOiBbXSxcbiAgICBvcHRpb25zOiBvcHRpb25zIHx8IHt9LFxuICAgIGVycm9yczogW11cbiAgfTtcbn1cbmV4cG9ydHMuUmVwb3J0ZXIgPSBSZXBvcnRlcjtcblxuUmVwb3J0ZXIucHJvdG90eXBlLmlzRXJyb3IgPSBmdW5jdGlvbiBpc0Vycm9yKG9iaikge1xuICByZXR1cm4gb2JqIGluc3RhbmNlb2YgUmVwb3J0ZXJFcnJvcjtcbn07XG5cblJlcG9ydGVyLnByb3RvdHlwZS5zYXZlID0gZnVuY3Rpb24gc2F2ZSgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVwb3J0ZXJTdGF0ZTtcblxuICByZXR1cm4geyBvYmo6IHN0YXRlLm9iaiwgcGF0aExlbjogc3RhdGUucGF0aC5sZW5ndGggfTtcbn07XG5cblJlcG9ydGVyLnByb3RvdHlwZS5yZXN0b3JlID0gZnVuY3Rpb24gcmVzdG9yZShkYXRhKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlcG9ydGVyU3RhdGU7XG5cbiAgc3RhdGUub2JqID0gZGF0YS5vYmo7XG4gIHN0YXRlLnBhdGggPSBzdGF0ZS5wYXRoLnNsaWNlKDAsIGRhdGEucGF0aExlbik7XG59O1xuXG5SZXBvcnRlci5wcm90b3R5cGUuZW50ZXJLZXkgPSBmdW5jdGlvbiBlbnRlcktleShrZXkpIHtcbiAgcmV0dXJuIHRoaXMuX3JlcG9ydGVyU3RhdGUucGF0aC5wdXNoKGtleSk7XG59O1xuXG5SZXBvcnRlci5wcm90b3R5cGUubGVhdmVLZXkgPSBmdW5jdGlvbiBsZWF2ZUtleShpbmRleCwga2V5LCB2YWx1ZSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZXBvcnRlclN0YXRlO1xuXG4gIHN0YXRlLnBhdGggPSBzdGF0ZS5wYXRoLnNsaWNlKDAsIGluZGV4IC0gMSk7XG4gIGlmIChzdGF0ZS5vYmogIT09IG51bGwpXG4gICAgc3RhdGUub2JqW2tleV0gPSB2YWx1ZTtcbn07XG5cblJlcG9ydGVyLnByb3RvdHlwZS5lbnRlck9iamVjdCA9IGZ1bmN0aW9uIGVudGVyT2JqZWN0KCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZXBvcnRlclN0YXRlO1xuXG4gIHZhciBwcmV2ID0gc3RhdGUub2JqO1xuICBzdGF0ZS5vYmogPSB7fTtcbiAgcmV0dXJuIHByZXY7XG59O1xuXG5SZXBvcnRlci5wcm90b3R5cGUubGVhdmVPYmplY3QgPSBmdW5jdGlvbiBsZWF2ZU9iamVjdChwcmV2KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlcG9ydGVyU3RhdGU7XG5cbiAgdmFyIG5vdyA9IHN0YXRlLm9iajtcbiAgc3RhdGUub2JqID0gcHJldjtcbiAgcmV0dXJuIG5vdztcbn07XG5cblJlcG9ydGVyLnByb3RvdHlwZS5lcnJvciA9IGZ1bmN0aW9uIGVycm9yKG1zZykge1xuICB2YXIgZXJyO1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZXBvcnRlclN0YXRlO1xuXG4gIHZhciBpbmhlcml0ZWQgPSBtc2cgaW5zdGFuY2VvZiBSZXBvcnRlckVycm9yO1xuICBpZiAoaW5oZXJpdGVkKSB7XG4gICAgZXJyID0gbXNnO1xuICB9IGVsc2Uge1xuICAgIGVyciA9IG5ldyBSZXBvcnRlckVycm9yKHN0YXRlLnBhdGgubWFwKGZ1bmN0aW9uKGVsZW0pIHtcbiAgICAgIHJldHVybiAnWycgKyBKU09OLnN0cmluZ2lmeShlbGVtKSArICddJztcbiAgICB9KS5qb2luKCcnKSwgbXNnLm1lc3NhZ2UgfHwgbXNnLCBtc2cuc3RhY2spO1xuICB9XG5cbiAgaWYgKCFzdGF0ZS5vcHRpb25zLnBhcnRpYWwpXG4gICAgdGhyb3cgZXJyO1xuXG4gIGlmICghaW5oZXJpdGVkKVxuICAgIHN0YXRlLmVycm9ycy5wdXNoKGVycik7XG5cbiAgcmV0dXJuIGVycjtcbn07XG5cblJlcG9ydGVyLnByb3RvdHlwZS53cmFwUmVzdWx0ID0gZnVuY3Rpb24gd3JhcFJlc3VsdChyZXN1bHQpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVwb3J0ZXJTdGF0ZTtcbiAgaWYgKCFzdGF0ZS5vcHRpb25zLnBhcnRpYWwpXG4gICAgcmV0dXJuIHJlc3VsdDtcblxuICByZXR1cm4ge1xuICAgIHJlc3VsdDogdGhpcy5pc0Vycm9yKHJlc3VsdCkgPyBudWxsIDogcmVzdWx0LFxuICAgIGVycm9yczogc3RhdGUuZXJyb3JzXG4gIH07XG59O1xuXG5mdW5jdGlvbiBSZXBvcnRlckVycm9yKHBhdGgsIG1zZykge1xuICB0aGlzLnBhdGggPSBwYXRoO1xuICB0aGlzLnJldGhyb3cobXNnKTtcbn07XG5pbmhlcml0cyhSZXBvcnRlckVycm9yLCBFcnJvcik7XG5cblJlcG9ydGVyRXJyb3IucHJvdG90eXBlLnJldGhyb3cgPSBmdW5jdGlvbiByZXRocm93KG1zZykge1xuICB0aGlzLm1lc3NhZ2UgPSBtc2cgKyAnIGF0OiAnICsgKHRoaXMucGF0aCB8fCAnKHNoYWxsb3cpJyk7XG4gIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIFJlcG9ydGVyRXJyb3IpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcbiIsInZhciBjb25zdGFudHMgPSByZXF1aXJlKCcuLi9jb25zdGFudHMnKTtcblxuZXhwb3J0cy50YWdDbGFzcyA9IHtcbiAgMDogJ3VuaXZlcnNhbCcsXG4gIDE6ICdhcHBsaWNhdGlvbicsXG4gIDI6ICdjb250ZXh0JyxcbiAgMzogJ3ByaXZhdGUnXG59O1xuZXhwb3J0cy50YWdDbGFzc0J5TmFtZSA9IGNvbnN0YW50cy5fcmV2ZXJzZShleHBvcnRzLnRhZ0NsYXNzKTtcblxuZXhwb3J0cy50YWcgPSB7XG4gIDB4MDA6ICdlbmQnLFxuICAweDAxOiAnYm9vbCcsXG4gIDB4MDI6ICdpbnQnLFxuICAweDAzOiAnYml0c3RyJyxcbiAgMHgwNDogJ29jdHN0cicsXG4gIDB4MDU6ICdudWxsXycsXG4gIDB4MDY6ICdvYmppZCcsXG4gIDB4MDc6ICdvYmpEZXNjJyxcbiAgMHgwODogJ2V4dGVybmFsJyxcbiAgMHgwOTogJ3JlYWwnLFxuICAweDBhOiAnZW51bScsXG4gIDB4MGI6ICdlbWJlZCcsXG4gIDB4MGM6ICd1dGY4c3RyJyxcbiAgMHgwZDogJ3JlbGF0aXZlT2lkJyxcbiAgMHgxMDogJ3NlcScsXG4gIDB4MTE6ICdzZXQnLFxuICAweDEyOiAnbnVtc3RyJyxcbiAgMHgxMzogJ3ByaW50c3RyJyxcbiAgMHgxNDogJ3Q2MXN0cicsXG4gIDB4MTU6ICd2aWRlb3N0cicsXG4gIDB4MTY6ICdpYTVzdHInLFxuICAweDE3OiAndXRjdGltZScsXG4gIDB4MTg6ICdnZW50aW1lJyxcbiAgMHgxOTogJ2dyYXBoc3RyJyxcbiAgMHgxYTogJ2lzbzY0NnN0cicsXG4gIDB4MWI6ICdnZW5zdHInLFxuICAweDFjOiAndW5pc3RyJyxcbiAgMHgxZDogJ2NoYXJzdHInLFxuICAweDFlOiAnYm1wc3RyJ1xufTtcbmV4cG9ydHMudGFnQnlOYW1lID0gY29uc3RhbnRzLl9yZXZlcnNlKGV4cG9ydHMudGFnKTtcbiIsInZhciBjb25zdGFudHMgPSBleHBvcnRzO1xuXG4vLyBIZWxwZXJcbmNvbnN0YW50cy5fcmV2ZXJzZSA9IGZ1bmN0aW9uIHJldmVyc2UobWFwKSB7XG4gIHZhciByZXMgPSB7fTtcblxuICBPYmplY3Qua2V5cyhtYXApLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgLy8gQ29udmVydCBrZXkgdG8gaW50ZWdlciBpZiBpdCBpcyBzdHJpbmdpZmllZFxuICAgIGlmICgoa2V5IHwgMCkgPT0ga2V5KVxuICAgICAga2V5ID0ga2V5IHwgMDtcblxuICAgIHZhciB2YWx1ZSA9IG1hcFtrZXldO1xuICAgIHJlc1t2YWx1ZV0gPSBrZXk7XG4gIH0pO1xuXG4gIHJldHVybiByZXM7XG59O1xuXG5jb25zdGFudHMuZGVyID0gcmVxdWlyZSgnLi9kZXInKTtcbiIsInZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbnZhciBhc24xID0gcmVxdWlyZSgnLi4vLi4vYXNuMScpO1xudmFyIGJhc2UgPSBhc24xLmJhc2U7XG52YXIgYmlnbnVtID0gYXNuMS5iaWdudW07XG5cbi8vIEltcG9ydCBERVIgY29uc3RhbnRzXG52YXIgZGVyID0gYXNuMS5jb25zdGFudHMuZGVyO1xuXG5mdW5jdGlvbiBERVJEZWNvZGVyKGVudGl0eSkge1xuICB0aGlzLmVuYyA9ICdkZXInO1xuICB0aGlzLm5hbWUgPSBlbnRpdHkubmFtZTtcbiAgdGhpcy5lbnRpdHkgPSBlbnRpdHk7XG5cbiAgLy8gQ29uc3RydWN0IGJhc2UgdHJlZVxuICB0aGlzLnRyZWUgPSBuZXcgREVSTm9kZSgpO1xuICB0aGlzLnRyZWUuX2luaXQoZW50aXR5LmJvZHkpO1xufTtcbm1vZHVsZS5leHBvcnRzID0gREVSRGVjb2RlcjtcblxuREVSRGVjb2Rlci5wcm90b3R5cGUuZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKGRhdGEsIG9wdGlvbnMpIHtcbiAgaWYgKCEoZGF0YSBpbnN0YW5jZW9mIGJhc2UuRGVjb2RlckJ1ZmZlcikpXG4gICAgZGF0YSA9IG5ldyBiYXNlLkRlY29kZXJCdWZmZXIoZGF0YSwgb3B0aW9ucyk7XG5cbiAgcmV0dXJuIHRoaXMudHJlZS5fZGVjb2RlKGRhdGEsIG9wdGlvbnMpO1xufTtcblxuLy8gVHJlZSBtZXRob2RzXG5cbmZ1bmN0aW9uIERFUk5vZGUocGFyZW50KSB7XG4gIGJhc2UuTm9kZS5jYWxsKHRoaXMsICdkZXInLCBwYXJlbnQpO1xufVxuaW5oZXJpdHMoREVSTm9kZSwgYmFzZS5Ob2RlKTtcblxuREVSTm9kZS5wcm90b3R5cGUuX3BlZWtUYWcgPSBmdW5jdGlvbiBwZWVrVGFnKGJ1ZmZlciwgdGFnLCBhbnkpIHtcbiAgaWYgKGJ1ZmZlci5pc0VtcHR5KCkpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBzdGF0ZSA9IGJ1ZmZlci5zYXZlKCk7XG4gIHZhciBkZWNvZGVkVGFnID0gZGVyRGVjb2RlVGFnKGJ1ZmZlciwgJ0ZhaWxlZCB0byBwZWVrIHRhZzogXCInICsgdGFnICsgJ1wiJyk7XG4gIGlmIChidWZmZXIuaXNFcnJvcihkZWNvZGVkVGFnKSlcbiAgICByZXR1cm4gZGVjb2RlZFRhZztcblxuICBidWZmZXIucmVzdG9yZShzdGF0ZSk7XG5cbiAgcmV0dXJuIGRlY29kZWRUYWcudGFnID09PSB0YWcgfHwgZGVjb2RlZFRhZy50YWdTdHIgPT09IHRhZyB8fCBhbnk7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZGVjb2RlVGFnID0gZnVuY3Rpb24gZGVjb2RlVGFnKGJ1ZmZlciwgdGFnLCBhbnkpIHtcbiAgdmFyIGRlY29kZWRUYWcgPSBkZXJEZWNvZGVUYWcoYnVmZmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRmFpbGVkIHRvIGRlY29kZSB0YWcgb2YgXCInICsgdGFnICsgJ1wiJyk7XG4gIGlmIChidWZmZXIuaXNFcnJvcihkZWNvZGVkVGFnKSlcbiAgICByZXR1cm4gZGVjb2RlZFRhZztcblxuICB2YXIgbGVuID0gZGVyRGVjb2RlTGVuKGJ1ZmZlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICBkZWNvZGVkVGFnLnByaW1pdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAnRmFpbGVkIHRvIGdldCBsZW5ndGggb2YgXCInICsgdGFnICsgJ1wiJyk7XG5cbiAgLy8gRmFpbHVyZVxuICBpZiAoYnVmZmVyLmlzRXJyb3IobGVuKSlcbiAgICByZXR1cm4gbGVuO1xuXG4gIGlmICghYW55ICYmXG4gICAgICBkZWNvZGVkVGFnLnRhZyAhPT0gdGFnICYmXG4gICAgICBkZWNvZGVkVGFnLnRhZ1N0ciAhPT0gdGFnICYmXG4gICAgICBkZWNvZGVkVGFnLnRhZ1N0ciArICdvZicgIT09IHRhZykge1xuICAgIHJldHVybiBidWZmZXIuZXJyb3IoJ0ZhaWxlZCB0byBtYXRjaCB0YWc6IFwiJyArIHRhZyArICdcIicpO1xuICB9XG5cbiAgaWYgKGRlY29kZWRUYWcucHJpbWl0aXZlIHx8IGxlbiAhPT0gbnVsbClcbiAgICByZXR1cm4gYnVmZmVyLnNraXAobGVuLCAnRmFpbGVkIHRvIG1hdGNoIGJvZHkgb2Y6IFwiJyArIHRhZyArICdcIicpO1xuXG4gIC8vIEluZGVmaW5pdGUgbGVuZ3RoLi4uIGZpbmQgRU5EIHRhZ1xuICB2YXIgc3RhdGUgPSBidWZmZXIuc2F2ZSgpO1xuICB2YXIgcmVzID0gdGhpcy5fc2tpcFVudGlsRW5kKFxuICAgICAgYnVmZmVyLFxuICAgICAgJ0ZhaWxlZCB0byBza2lwIGluZGVmaW5pdGUgbGVuZ3RoIGJvZHk6IFwiJyArIHRoaXMudGFnICsgJ1wiJyk7XG4gIGlmIChidWZmZXIuaXNFcnJvcihyZXMpKVxuICAgIHJldHVybiByZXM7XG5cbiAgbGVuID0gYnVmZmVyLm9mZnNldCAtIHN0YXRlLm9mZnNldDtcbiAgYnVmZmVyLnJlc3RvcmUoc3RhdGUpO1xuICByZXR1cm4gYnVmZmVyLnNraXAobGVuLCAnRmFpbGVkIHRvIG1hdGNoIGJvZHkgb2Y6IFwiJyArIHRhZyArICdcIicpO1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX3NraXBVbnRpbEVuZCA9IGZ1bmN0aW9uIHNraXBVbnRpbEVuZChidWZmZXIsIGZhaWwpIHtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICB2YXIgdGFnID0gZGVyRGVjb2RlVGFnKGJ1ZmZlciwgZmFpbCk7XG4gICAgaWYgKGJ1ZmZlci5pc0Vycm9yKHRhZykpXG4gICAgICByZXR1cm4gdGFnO1xuICAgIHZhciBsZW4gPSBkZXJEZWNvZGVMZW4oYnVmZmVyLCB0YWcucHJpbWl0aXZlLCBmYWlsKTtcbiAgICBpZiAoYnVmZmVyLmlzRXJyb3IobGVuKSlcbiAgICAgIHJldHVybiBsZW47XG5cbiAgICB2YXIgcmVzO1xuICAgIGlmICh0YWcucHJpbWl0aXZlIHx8IGxlbiAhPT0gbnVsbClcbiAgICAgIHJlcyA9IGJ1ZmZlci5za2lwKGxlbilcbiAgICBlbHNlXG4gICAgICByZXMgPSB0aGlzLl9za2lwVW50aWxFbmQoYnVmZmVyLCBmYWlsKTtcblxuICAgIC8vIEZhaWx1cmVcbiAgICBpZiAoYnVmZmVyLmlzRXJyb3IocmVzKSlcbiAgICAgIHJldHVybiByZXM7XG5cbiAgICBpZiAodGFnLnRhZ1N0ciA9PT0gJ2VuZCcpXG4gICAgICBicmVhaztcbiAgfVxufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2RlY29kZUxpc3QgPSBmdW5jdGlvbiBkZWNvZGVMaXN0KGJ1ZmZlciwgdGFnLCBkZWNvZGVyKSB7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgd2hpbGUgKCFidWZmZXIuaXNFbXB0eSgpKSB7XG4gICAgdmFyIHBvc3NpYmxlRW5kID0gdGhpcy5fcGVla1RhZyhidWZmZXIsICdlbmQnKTtcbiAgICBpZiAoYnVmZmVyLmlzRXJyb3IocG9zc2libGVFbmQpKVxuICAgICAgcmV0dXJuIHBvc3NpYmxlRW5kO1xuXG4gICAgdmFyIHJlcyA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlciwgJ2RlcicpO1xuICAgIGlmIChidWZmZXIuaXNFcnJvcihyZXMpICYmIHBvc3NpYmxlRW5kKVxuICAgICAgYnJlYWs7XG4gICAgcmVzdWx0LnB1c2gocmVzKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2RlY29kZVN0ciA9IGZ1bmN0aW9uIGRlY29kZVN0cihidWZmZXIsIHRhZykge1xuICBpZiAodGFnID09PSAnb2N0c3RyJykge1xuICAgIHJldHVybiBidWZmZXIucmF3KCk7XG4gIH0gZWxzZSBpZiAodGFnID09PSAnYml0c3RyJykge1xuICAgIHZhciB1bnVzZWQgPSBidWZmZXIucmVhZFVJbnQ4KCk7XG4gICAgaWYgKGJ1ZmZlci5pc0Vycm9yKHVudXNlZCkpXG4gICAgICByZXR1cm4gdW51c2VkO1xuXG4gICAgcmV0dXJuIHsgdW51c2VkOiB1bnVzZWQsIGRhdGE6IGJ1ZmZlci5yYXcoKSB9O1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ2lhNXN0cicgfHwgdGFnID09PSAndXRmOHN0cicpIHtcbiAgICByZXR1cm4gYnVmZmVyLnJhdygpLnRvU3RyaW5nKCk7XG4gIH0gZWxzZSBpZih0YWcgPT09ICdudW1zdHInKSB7XG4gICAgdmFyIG51bXN0ciA9IGJ1ZmZlci5yYXcoKS50b1N0cmluZygnYXNjaWknKTtcbiAgICBpZiAoIXRoaXMuX2lzTnVtc3RyKG51bXN0cikpIHtcbiAgICAgIHJldHVybiBidWZmZXIuZXJyb3IoJ0RlY29kaW5nIG9mIHN0cmluZyB0eXBlOiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ251bXN0ciB1bnN1cHBvcnRlZCBjaGFyYWN0ZXJzJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bXN0cjtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICdwcmludHN0cicpIHtcbiAgICB2YXIgcHJpbnRzdHIgPSBidWZmZXIucmF3KCkudG9TdHJpbmcoJ2FzY2lpJyk7XG4gICAgaWYgKCF0aGlzLl9pc1ByaW50c3RyKHByaW50c3RyKSkge1xuICAgICAgcmV0dXJuIGJ1ZmZlci5lcnJvcignRGVjb2Rpbmcgb2Ygc3RyaW5nIHR5cGU6ICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAncHJpbnRzdHIgdW5zdXBwb3J0ZWQgY2hhcmFjdGVycycpO1xuICAgIH1cblxuICAgIHJldHVybiBwcmludHN0cjtcbiAgfSBlbHNlIGlmKHRhZyA9PT0gJ2JtcHN0cicpIHtcbiAgICB2YXIgcmF3ID0gYnVmZmVyLnJhdygpO1xuICAgIGlmIChyYXcubGVuZ3RoICUgMiA9PT0gMSlcbiAgICAgIHJldHVybiBidWZmZXIuZXJyb3IoJ0RlY29kaW5nIG9mIHN0cmluZyB0eXBlOiBibXBzdHIgbGVuZ3RoIG1pc21hdGNoJyk7XG5cbiAgICB2YXIgc3RyID0gJyc7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCByYXcubGVuZ3RoIC8gMjsgaSsrKSB7XG4gICAgICBzdHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShyYXcucmVhZFVJbnQxNkJFKGkgKiAyKSk7XG4gICAgfVxuICAgIHJldHVybiBzdHI7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJ1ZmZlci5lcnJvcignRGVjb2Rpbmcgb2Ygc3RyaW5nIHR5cGU6ICcgKyB0YWcgKyAnIHVuc3VwcG9ydGVkJyk7XG4gIH1cbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9kZWNvZGVPYmppZCA9IGZ1bmN0aW9uIGRlY29kZU9iamlkKGJ1ZmZlciwgdmFsdWVzLCByZWxhdGl2ZSkge1xuICB2YXIgaWRlbnRpZmllcnMgPSBbXTtcbiAgdmFyIGlkZW50ID0gMDtcbiAgd2hpbGUgKCFidWZmZXIuaXNFbXB0eSgpKSB7XG4gICAgdmFyIHN1YmlkZW50ID0gYnVmZmVyLnJlYWRVSW50OCgpO1xuICAgIGlkZW50IDw8PSA3O1xuICAgIGlkZW50IHw9IHN1YmlkZW50ICYgMHg3ZjtcbiAgICBpZiAoKHN1YmlkZW50ICYgMHg4MCkgPT09IDApIHtcbiAgICAgIGlkZW50aWZpZXJzLnB1c2goaWRlbnQpO1xuICAgICAgaWRlbnQgPSAwO1xuICAgIH1cbiAgfVxuICBpZiAoc3ViaWRlbnQgJiAweDgwKVxuICAgIGlkZW50aWZpZXJzLnB1c2goaWRlbnQpO1xuXG4gIHZhciBmaXJzdCA9IChpZGVudGlmaWVyc1swXSAvIDQwKSB8IDA7XG4gIHZhciBzZWNvbmQgPSBpZGVudGlmaWVyc1swXSAlIDQwO1xuXG4gIGlmIChyZWxhdGl2ZSlcbiAgICByZXN1bHQgPSBpZGVudGlmaWVycztcbiAgZWxzZVxuICAgIHJlc3VsdCA9IFtmaXJzdCwgc2Vjb25kXS5jb25jYXQoaWRlbnRpZmllcnMuc2xpY2UoMSkpO1xuXG4gIGlmICh2YWx1ZXMpIHtcbiAgICB2YXIgdG1wID0gdmFsdWVzW3Jlc3VsdC5qb2luKCcgJyldO1xuICAgIGlmICh0bXAgPT09IHVuZGVmaW5lZClcbiAgICAgIHRtcCA9IHZhbHVlc1tyZXN1bHQuam9pbignLicpXTtcbiAgICBpZiAodG1wICE9PSB1bmRlZmluZWQpXG4gICAgICByZXN1bHQgPSB0bXA7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2RlY29kZVRpbWUgPSBmdW5jdGlvbiBkZWNvZGVUaW1lKGJ1ZmZlciwgdGFnKSB7XG4gIHZhciBzdHIgPSBidWZmZXIucmF3KCkudG9TdHJpbmcoKTtcbiAgaWYgKHRhZyA9PT0gJ2dlbnRpbWUnKSB7XG4gICAgdmFyIHllYXIgPSBzdHIuc2xpY2UoMCwgNCkgfCAwO1xuICAgIHZhciBtb24gPSBzdHIuc2xpY2UoNCwgNikgfCAwO1xuICAgIHZhciBkYXkgPSBzdHIuc2xpY2UoNiwgOCkgfCAwO1xuICAgIHZhciBob3VyID0gc3RyLnNsaWNlKDgsIDEwKSB8IDA7XG4gICAgdmFyIG1pbiA9IHN0ci5zbGljZSgxMCwgMTIpIHwgMDtcbiAgICB2YXIgc2VjID0gc3RyLnNsaWNlKDEyLCAxNCkgfCAwO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ3V0Y3RpbWUnKSB7XG4gICAgdmFyIHllYXIgPSBzdHIuc2xpY2UoMCwgMikgfCAwO1xuICAgIHZhciBtb24gPSBzdHIuc2xpY2UoMiwgNCkgfCAwO1xuICAgIHZhciBkYXkgPSBzdHIuc2xpY2UoNCwgNikgfCAwO1xuICAgIHZhciBob3VyID0gc3RyLnNsaWNlKDYsIDgpIHwgMDtcbiAgICB2YXIgbWluID0gc3RyLnNsaWNlKDgsIDEwKSB8IDA7XG4gICAgdmFyIHNlYyA9IHN0ci5zbGljZSgxMCwgMTIpIHwgMDtcbiAgICBpZiAoeWVhciA8IDcwKVxuICAgICAgeWVhciA9IDIwMDAgKyB5ZWFyO1xuICAgIGVsc2VcbiAgICAgIHllYXIgPSAxOTAwICsgeWVhcjtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYnVmZmVyLmVycm9yKCdEZWNvZGluZyAnICsgdGFnICsgJyB0aW1lIGlzIG5vdCBzdXBwb3J0ZWQgeWV0Jyk7XG4gIH1cblxuICByZXR1cm4gRGF0ZS5VVEMoeWVhciwgbW9uIC0gMSwgZGF5LCBob3VyLCBtaW4sIHNlYywgMCk7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZGVjb2RlTnVsbCA9IGZ1bmN0aW9uIGRlY29kZU51bGwoYnVmZmVyKSB7XG4gIHJldHVybiBudWxsO1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2RlY29kZUJvb2wgPSBmdW5jdGlvbiBkZWNvZGVCb29sKGJ1ZmZlcikge1xuICB2YXIgcmVzID0gYnVmZmVyLnJlYWRVSW50OCgpO1xuICBpZiAoYnVmZmVyLmlzRXJyb3IocmVzKSlcbiAgICByZXR1cm4gcmVzO1xuICBlbHNlXG4gICAgcmV0dXJuIHJlcyAhPT0gMDtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9kZWNvZGVJbnQgPSBmdW5jdGlvbiBkZWNvZGVJbnQoYnVmZmVyLCB2YWx1ZXMpIHtcbiAgLy8gQmlnaW50LCByZXR1cm4gYXMgaXQgaXMgKGFzc3VtZSBiaWcgZW5kaWFuKVxuICB2YXIgcmF3ID0gYnVmZmVyLnJhdygpO1xuICB2YXIgcmVzID0gbmV3IGJpZ251bShyYXcpO1xuXG4gIGlmICh2YWx1ZXMpXG4gICAgcmVzID0gdmFsdWVzW3Jlcy50b1N0cmluZygxMCldIHx8IHJlcztcblxuICByZXR1cm4gcmVzO1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX3VzZSA9IGZ1bmN0aW9uIHVzZShlbnRpdHksIG9iaikge1xuICBpZiAodHlwZW9mIGVudGl0eSA9PT0gJ2Z1bmN0aW9uJylcbiAgICBlbnRpdHkgPSBlbnRpdHkob2JqKTtcbiAgcmV0dXJuIGVudGl0eS5fZ2V0RGVjb2RlcignZGVyJykudHJlZTtcbn07XG5cbi8vIFV0aWxpdHkgbWV0aG9kc1xuXG5mdW5jdGlvbiBkZXJEZWNvZGVUYWcoYnVmLCBmYWlsKSB7XG4gIHZhciB0YWcgPSBidWYucmVhZFVJbnQ4KGZhaWwpO1xuICBpZiAoYnVmLmlzRXJyb3IodGFnKSlcbiAgICByZXR1cm4gdGFnO1xuXG4gIHZhciBjbHMgPSBkZXIudGFnQ2xhc3NbdGFnID4+IDZdO1xuICB2YXIgcHJpbWl0aXZlID0gKHRhZyAmIDB4MjApID09PSAwO1xuXG4gIC8vIE11bHRpLW9jdGV0IHRhZyAtIGxvYWRcbiAgaWYgKCh0YWcgJiAweDFmKSA9PT0gMHgxZikge1xuICAgIHZhciBvY3QgPSB0YWc7XG4gICAgdGFnID0gMDtcbiAgICB3aGlsZSAoKG9jdCAmIDB4ODApID09PSAweDgwKSB7XG4gICAgICBvY3QgPSBidWYucmVhZFVJbnQ4KGZhaWwpO1xuICAgICAgaWYgKGJ1Zi5pc0Vycm9yKG9jdCkpXG4gICAgICAgIHJldHVybiBvY3Q7XG5cbiAgICAgIHRhZyA8PD0gNztcbiAgICAgIHRhZyB8PSBvY3QgJiAweDdmO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0YWcgJj0gMHgxZjtcbiAgfVxuICB2YXIgdGFnU3RyID0gZGVyLnRhZ1t0YWddO1xuXG4gIHJldHVybiB7XG4gICAgY2xzOiBjbHMsXG4gICAgcHJpbWl0aXZlOiBwcmltaXRpdmUsXG4gICAgdGFnOiB0YWcsXG4gICAgdGFnU3RyOiB0YWdTdHJcbiAgfTtcbn1cblxuZnVuY3Rpb24gZGVyRGVjb2RlTGVuKGJ1ZiwgcHJpbWl0aXZlLCBmYWlsKSB7XG4gIHZhciBsZW4gPSBidWYucmVhZFVJbnQ4KGZhaWwpO1xuICBpZiAoYnVmLmlzRXJyb3IobGVuKSlcbiAgICByZXR1cm4gbGVuO1xuXG4gIC8vIEluZGVmaW5pdGUgZm9ybVxuICBpZiAoIXByaW1pdGl2ZSAmJiBsZW4gPT09IDB4ODApXG4gICAgcmV0dXJuIG51bGw7XG5cbiAgLy8gRGVmaW5pdGUgZm9ybVxuICBpZiAoKGxlbiAmIDB4ODApID09PSAwKSB7XG4gICAgLy8gU2hvcnQgZm9ybVxuICAgIHJldHVybiBsZW47XG4gIH1cblxuICAvLyBMb25nIGZvcm1cbiAgdmFyIG51bSA9IGxlbiAmIDB4N2Y7XG4gIGlmIChudW0gPj0gNClcbiAgICByZXR1cm4gYnVmLmVycm9yKCdsZW5ndGggb2N0ZWN0IGlzIHRvbyBsb25nJyk7XG5cbiAgbGVuID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW07IGkrKykge1xuICAgIGxlbiA8PD0gODtcbiAgICB2YXIgaiA9IGJ1Zi5yZWFkVUludDgoZmFpbCk7XG4gICAgaWYgKGJ1Zi5pc0Vycm9yKGopKVxuICAgICAgcmV0dXJuIGo7XG4gICAgbGVuIHw9IGo7XG4gIH1cblxuICByZXR1cm4gbGVuO1xufVxuIiwidmFyIGRlY29kZXJzID0gZXhwb3J0cztcblxuZGVjb2RlcnMuZGVyID0gcmVxdWlyZSgnLi9kZXInKTtcbmRlY29kZXJzLnBlbSA9IHJlcXVpcmUoJy4vcGVtJyk7XG4iLCJ2YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcblxudmFyIGFzbjEgPSByZXF1aXJlKCcuLi8uLi9hc24xJyk7XG52YXIgREVSRGVjb2RlciA9IHJlcXVpcmUoJy4vZGVyJyk7XG5cbmZ1bmN0aW9uIFBFTURlY29kZXIoZW50aXR5KSB7XG4gIERFUkRlY29kZXIuY2FsbCh0aGlzLCBlbnRpdHkpO1xuICB0aGlzLmVuYyA9ICdwZW0nO1xufTtcbmluaGVyaXRzKFBFTURlY29kZXIsIERFUkRlY29kZXIpO1xubW9kdWxlLmV4cG9ydHMgPSBQRU1EZWNvZGVyO1xuXG5QRU1EZWNvZGVyLnByb3RvdHlwZS5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUoZGF0YSwgb3B0aW9ucykge1xuICB2YXIgbGluZXMgPSBkYXRhLnRvU3RyaW5nKCkuc3BsaXQoL1tcXHJcXG5dKy9nKTtcblxuICB2YXIgbGFiZWwgPSBvcHRpb25zLmxhYmVsLnRvVXBwZXJDYXNlKCk7XG5cbiAgdmFyIHJlID0gL14tLS0tLShCRUdJTnxFTkQpIChbXi1dKyktLS0tLSQvO1xuICB2YXIgc3RhcnQgPSAtMTtcbiAgdmFyIGVuZCA9IC0xO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIG1hdGNoID0gbGluZXNbaV0ubWF0Y2gocmUpO1xuICAgIGlmIChtYXRjaCA9PT0gbnVsbClcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgaWYgKG1hdGNoWzJdICE9PSBsYWJlbClcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgaWYgKHN0YXJ0ID09PSAtMSkge1xuICAgICAgaWYgKG1hdGNoWzFdICE9PSAnQkVHSU4nKVxuICAgICAgICBicmVhaztcbiAgICAgIHN0YXJ0ID0gaTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKG1hdGNoWzFdICE9PSAnRU5EJylcbiAgICAgICAgYnJlYWs7XG4gICAgICBlbmQgPSBpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmIChzdGFydCA9PT0gLTEgfHwgZW5kID09PSAtMSlcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BFTSBzZWN0aW9uIG5vdCBmb3VuZCBmb3I6ICcgKyBsYWJlbCk7XG5cbiAgdmFyIGJhc2U2NCA9IGxpbmVzLnNsaWNlKHN0YXJ0ICsgMSwgZW5kKS5qb2luKCcnKTtcbiAgLy8gUmVtb3ZlIGV4Y2Vzc2l2ZSBzeW1ib2xzXG4gIGJhc2U2NC5yZXBsYWNlKC9bXmEtejAtOVxcK1xcLz1dKy9naSwgJycpO1xuXG4gIHZhciBpbnB1dCA9IG5ldyBCdWZmZXIoYmFzZTY0LCAnYmFzZTY0Jyk7XG4gIHJldHVybiBERVJEZWNvZGVyLnByb3RvdHlwZS5kZWNvZGUuY2FsbCh0aGlzLCBpbnB1dCwgb3B0aW9ucyk7XG59O1xuIiwidmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG5cbnZhciBhc24xID0gcmVxdWlyZSgnLi4vLi4vYXNuMScpO1xudmFyIGJhc2UgPSBhc24xLmJhc2U7XG52YXIgYmlnbnVtID0gYXNuMS5iaWdudW07XG5cbi8vIEltcG9ydCBERVIgY29uc3RhbnRzXG52YXIgZGVyID0gYXNuMS5jb25zdGFudHMuZGVyO1xuXG5mdW5jdGlvbiBERVJFbmNvZGVyKGVudGl0eSkge1xuICB0aGlzLmVuYyA9ICdkZXInO1xuICB0aGlzLm5hbWUgPSBlbnRpdHkubmFtZTtcbiAgdGhpcy5lbnRpdHkgPSBlbnRpdHk7XG5cbiAgLy8gQ29uc3RydWN0IGJhc2UgdHJlZVxuICB0aGlzLnRyZWUgPSBuZXcgREVSTm9kZSgpO1xuICB0aGlzLnRyZWUuX2luaXQoZW50aXR5LmJvZHkpO1xufTtcbm1vZHVsZS5leHBvcnRzID0gREVSRW5jb2RlcjtcblxuREVSRW5jb2Rlci5wcm90b3R5cGUuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKGRhdGEsIHJlcG9ydGVyKSB7XG4gIHJldHVybiB0aGlzLnRyZWUuX2VuY29kZShkYXRhLCByZXBvcnRlcikuam9pbigpO1xufTtcblxuLy8gVHJlZSBtZXRob2RzXG5cbmZ1bmN0aW9uIERFUk5vZGUocGFyZW50KSB7XG4gIGJhc2UuTm9kZS5jYWxsKHRoaXMsICdkZXInLCBwYXJlbnQpO1xufVxuaW5oZXJpdHMoREVSTm9kZSwgYmFzZS5Ob2RlKTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2VuY29kZUNvbXBvc2l0ZSA9IGZ1bmN0aW9uIGVuY29kZUNvbXBvc2l0ZSh0YWcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW1pdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50KSB7XG4gIHZhciBlbmNvZGVkVGFnID0gZW5jb2RlVGFnKHRhZywgcHJpbWl0aXZlLCBjbHMsIHRoaXMucmVwb3J0ZXIpO1xuXG4gIC8vIFNob3J0IGZvcm1cbiAgaWYgKGNvbnRlbnQubGVuZ3RoIDwgMHg4MCkge1xuICAgIHZhciBoZWFkZXIgPSBuZXcgQnVmZmVyKDIpO1xuICAgIGhlYWRlclswXSA9IGVuY29kZWRUYWc7XG4gICAgaGVhZGVyWzFdID0gY29udGVudC5sZW5ndGg7XG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoWyBoZWFkZXIsIGNvbnRlbnQgXSk7XG4gIH1cblxuICAvLyBMb25nIGZvcm1cbiAgLy8gQ291bnQgb2N0ZXRzIHJlcXVpcmVkIHRvIHN0b3JlIGxlbmd0aFxuICB2YXIgbGVuT2N0ZXRzID0gMTtcbiAgZm9yICh2YXIgaSA9IGNvbnRlbnQubGVuZ3RoOyBpID49IDB4MTAwOyBpID4+PSA4KVxuICAgIGxlbk9jdGV0cysrO1xuXG4gIHZhciBoZWFkZXIgPSBuZXcgQnVmZmVyKDEgKyAxICsgbGVuT2N0ZXRzKTtcbiAgaGVhZGVyWzBdID0gZW5jb2RlZFRhZztcbiAgaGVhZGVyWzFdID0gMHg4MCB8IGxlbk9jdGV0cztcblxuICBmb3IgKHZhciBpID0gMSArIGxlbk9jdGV0cywgaiA9IGNvbnRlbnQubGVuZ3RoOyBqID4gMDsgaS0tLCBqID4+PSA4KVxuICAgIGhlYWRlcltpXSA9IGogJiAweGZmO1xuXG4gIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKFsgaGVhZGVyLCBjb250ZW50IF0pO1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2VuY29kZVN0ciA9IGZ1bmN0aW9uIGVuY29kZVN0cihzdHIsIHRhZykge1xuICBpZiAodGFnID09PSAnb2N0c3RyJykge1xuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKHN0cik7XG4gIH0gZWxzZSBpZiAodGFnID09PSAnYml0c3RyJykge1xuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKFsgc3RyLnVudXNlZCB8IDAsIHN0ci5kYXRhIF0pO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ2lhNXN0cicgfHwgdGFnID09PSAndXRmOHN0cicpIHtcbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihzdHIpO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ2JtcHN0cicpIHtcbiAgICB2YXIgYnVmID0gbmV3IEJ1ZmZlcihzdHIubGVuZ3RoICogMik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICAgIGJ1Zi53cml0ZVVJbnQxNkJFKHN0ci5jaGFyQ29kZUF0KGkpLCBpICogMik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKGJ1Zik7XG4gIH0gZWxzZSBpZiAodGFnID09PSAnbnVtc3RyJykge1xuICAgIGlmICghdGhpcy5faXNOdW1zdHIoc3RyKSkge1xuICAgICAgcmV0dXJuIHRoaXMucmVwb3J0ZXIuZXJyb3IoJ0VuY29kaW5nIG9mIHN0cmluZyB0eXBlOiBudW1zdHIgc3VwcG9ydHMgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnb25seSBkaWdpdHMgYW5kIHNwYWNlJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoc3RyKTtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICdwcmludHN0cicpIHtcbiAgICBpZiAoIXRoaXMuX2lzUHJpbnRzdHIoc3RyKSkge1xuICAgICAgcmV0dXJuIHRoaXMucmVwb3J0ZXIuZXJyb3IoJ0VuY29kaW5nIG9mIHN0cmluZyB0eXBlOiBwcmludHN0ciBzdXBwb3J0cyAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdvbmx5IGxhdGluIHVwcGVyIGFuZCBsb3dlciBjYXNlIGxldHRlcnMsICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2RpZ2l0cywgc3BhY2UsIGFwb3N0cm9waGUsIGxlZnQgYW5kIHJpZ3RoICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3BhcmVudGhlc2lzLCBwbHVzIHNpZ24sIGNvbW1hLCBoeXBoZW4sICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2RvdCwgc2xhc2gsIGNvbG9uLCBlcXVhbCBzaWduLCAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdxdWVzdGlvbiBtYXJrJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoc3RyKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdGhpcy5yZXBvcnRlci5lcnJvcignRW5jb2Rpbmcgb2Ygc3RyaW5nIHR5cGU6ICcgKyB0YWcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgdW5zdXBwb3J0ZWQnKTtcbiAgfVxufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2VuY29kZU9iamlkID0gZnVuY3Rpb24gZW5jb2RlT2JqaWQoaWQsIHZhbHVlcywgcmVsYXRpdmUpIHtcbiAgaWYgKHR5cGVvZiBpZCA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAoIXZhbHVlcylcbiAgICAgIHJldHVybiB0aGlzLnJlcG9ydGVyLmVycm9yKCdzdHJpbmcgb2JqaWQgZ2l2ZW4sIGJ1dCBubyB2YWx1ZXMgbWFwIGZvdW5kJyk7XG4gICAgaWYgKCF2YWx1ZXMuaGFzT3duUHJvcGVydHkoaWQpKVxuICAgICAgcmV0dXJuIHRoaXMucmVwb3J0ZXIuZXJyb3IoJ29iamlkIG5vdCBmb3VuZCBpbiB2YWx1ZXMgbWFwJyk7XG4gICAgaWQgPSB2YWx1ZXNbaWRdLnNwbGl0KC9bXFxzXFwuXSsvZyk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpZC5sZW5ndGg7IGkrKylcbiAgICAgIGlkW2ldIHw9IDA7XG4gIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShpZCkpIHtcbiAgICBpZCA9IGlkLnNsaWNlKCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpZC5sZW5ndGg7IGkrKylcbiAgICAgIGlkW2ldIHw9IDA7XG4gIH1cblxuICBpZiAoIUFycmF5LmlzQXJyYXkoaWQpKSB7XG4gICAgcmV0dXJuIHRoaXMucmVwb3J0ZXIuZXJyb3IoJ29iamlkKCkgc2hvdWxkIGJlIGVpdGhlciBhcnJheSBvciBzdHJpbmcsICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdnb3Q6ICcgKyBKU09OLnN0cmluZ2lmeShpZCkpO1xuICB9XG5cbiAgaWYgKCFyZWxhdGl2ZSkge1xuICAgIGlmIChpZFsxXSA+PSA0MClcbiAgICAgIHJldHVybiB0aGlzLnJlcG9ydGVyLmVycm9yKCdTZWNvbmQgb2JqaWQgaWRlbnRpZmllciBPT0InKTtcbiAgICBpZC5zcGxpY2UoMCwgMiwgaWRbMF0gKiA0MCArIGlkWzFdKTtcbiAgfVxuXG4gIC8vIENvdW50IG51bWJlciBvZiBvY3RldHNcbiAgdmFyIHNpemUgPSAwO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGlkLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGlkZW50ID0gaWRbaV07XG4gICAgZm9yIChzaXplKys7IGlkZW50ID49IDB4ODA7IGlkZW50ID4+PSA3KVxuICAgICAgc2l6ZSsrO1xuICB9XG5cbiAgdmFyIG9iamlkID0gbmV3IEJ1ZmZlcihzaXplKTtcbiAgdmFyIG9mZnNldCA9IG9iamlkLmxlbmd0aCAtIDE7XG4gIGZvciAodmFyIGkgPSBpZC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIHZhciBpZGVudCA9IGlkW2ldO1xuICAgIG9iamlkW29mZnNldC0tXSA9IGlkZW50ICYgMHg3ZjtcbiAgICB3aGlsZSAoKGlkZW50ID4+PSA3KSA+IDApXG4gICAgICBvYmppZFtvZmZzZXQtLV0gPSAweDgwIHwgKGlkZW50ICYgMHg3Zik7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihvYmppZCk7XG59O1xuXG5mdW5jdGlvbiB0d28obnVtKSB7XG4gIGlmIChudW0gPCAxMClcbiAgICByZXR1cm4gJzAnICsgbnVtO1xuICBlbHNlXG4gICAgcmV0dXJuIG51bTtcbn1cblxuREVSTm9kZS5wcm90b3R5cGUuX2VuY29kZVRpbWUgPSBmdW5jdGlvbiBlbmNvZGVUaW1lKHRpbWUsIHRhZykge1xuICB2YXIgc3RyO1xuICB2YXIgZGF0ZSA9IG5ldyBEYXRlKHRpbWUpO1xuXG4gIGlmICh0YWcgPT09ICdnZW50aW1lJykge1xuICAgIHN0ciA9IFtcbiAgICAgIHR3byhkYXRlLmdldEZ1bGxZZWFyKCkpLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDTW9udGgoKSArIDEpLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDRGF0ZSgpKSxcbiAgICAgIHR3byhkYXRlLmdldFVUQ0hvdXJzKCkpLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDTWludXRlcygpKSxcbiAgICAgIHR3byhkYXRlLmdldFVUQ1NlY29uZHMoKSksXG4gICAgICAnWidcbiAgICBdLmpvaW4oJycpO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ3V0Y3RpbWUnKSB7XG4gICAgc3RyID0gW1xuICAgICAgdHdvKGRhdGUuZ2V0RnVsbFllYXIoKSAlIDEwMCksXG4gICAgICB0d28oZGF0ZS5nZXRVVENNb250aCgpICsgMSksXG4gICAgICB0d28oZGF0ZS5nZXRVVENEYXRlKCkpLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDSG91cnMoKSksXG4gICAgICB0d28oZGF0ZS5nZXRVVENNaW51dGVzKCkpLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDU2Vjb25kcygpKSxcbiAgICAgICdaJ1xuICAgIF0uam9pbignJyk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5yZXBvcnRlci5lcnJvcignRW5jb2RpbmcgJyArIHRhZyArICcgdGltZSBpcyBub3Qgc3VwcG9ydGVkIHlldCcpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuX2VuY29kZVN0cihzdHIsICdvY3RzdHInKTtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9lbmNvZGVOdWxsID0gZnVuY3Rpb24gZW5jb2RlTnVsbCgpIHtcbiAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoJycpO1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2VuY29kZUludCA9IGZ1bmN0aW9uIGVuY29kZUludChudW0sIHZhbHVlcykge1xuICBpZiAodHlwZW9mIG51bSA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAoIXZhbHVlcylcbiAgICAgIHJldHVybiB0aGlzLnJlcG9ydGVyLmVycm9yKCdTdHJpbmcgaW50IG9yIGVudW0gZ2l2ZW4sIGJ1dCBubyB2YWx1ZXMgbWFwJyk7XG4gICAgaWYgKCF2YWx1ZXMuaGFzT3duUHJvcGVydHkobnVtKSkge1xuICAgICAgcmV0dXJuIHRoaXMucmVwb3J0ZXIuZXJyb3IoJ1ZhbHVlcyBtYXAgZG9lc25cXCd0IGNvbnRhaW46ICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkobnVtKSk7XG4gICAgfVxuICAgIG51bSA9IHZhbHVlc1tudW1dO1xuICB9XG5cbiAgLy8gQmlnbnVtLCBhc3N1bWUgYmlnIGVuZGlhblxuICBpZiAodHlwZW9mIG51bSAhPT0gJ251bWJlcicgJiYgIUJ1ZmZlci5pc0J1ZmZlcihudW0pKSB7XG4gICAgdmFyIG51bUFycmF5ID0gbnVtLnRvQXJyYXkoKTtcbiAgICBpZiAoIW51bS5zaWduICYmIG51bUFycmF5WzBdICYgMHg4MCkge1xuICAgICAgbnVtQXJyYXkudW5zaGlmdCgwKTtcbiAgICB9XG4gICAgbnVtID0gbmV3IEJ1ZmZlcihudW1BcnJheSk7XG4gIH1cblxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKG51bSkpIHtcbiAgICB2YXIgc2l6ZSA9IG51bS5sZW5ndGg7XG4gICAgaWYgKG51bS5sZW5ndGggPT09IDApXG4gICAgICBzaXplKys7XG5cbiAgICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihzaXplKTtcbiAgICBudW0uY29weShvdXQpO1xuICAgIGlmIChudW0ubGVuZ3RoID09PSAwKVxuICAgICAgb3V0WzBdID0gMFxuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKG91dCk7XG4gIH1cblxuICBpZiAobnVtIDwgMHg4MClcbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihudW0pO1xuXG4gIGlmIChudW0gPCAweDEwMClcbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihbMCwgbnVtXSk7XG5cbiAgdmFyIHNpemUgPSAxO1xuICBmb3IgKHZhciBpID0gbnVtOyBpID49IDB4MTAwOyBpID4+PSA4KVxuICAgIHNpemUrKztcblxuICB2YXIgb3V0ID0gbmV3IEFycmF5KHNpemUpO1xuICBmb3IgKHZhciBpID0gb3V0Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgb3V0W2ldID0gbnVtICYgMHhmZjtcbiAgICBudW0gPj49IDg7XG4gIH1cbiAgaWYob3V0WzBdICYgMHg4MCkge1xuICAgIG91dC51bnNoaWZ0KDApO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIobmV3IEJ1ZmZlcihvdXQpKTtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9lbmNvZGVCb29sID0gZnVuY3Rpb24gZW5jb2RlQm9vbCh2YWx1ZSkge1xuICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcih2YWx1ZSA/IDB4ZmYgOiAwKTtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl91c2UgPSBmdW5jdGlvbiB1c2UoZW50aXR5LCBvYmopIHtcbiAgaWYgKHR5cGVvZiBlbnRpdHkgPT09ICdmdW5jdGlvbicpXG4gICAgZW50aXR5ID0gZW50aXR5KG9iaik7XG4gIHJldHVybiBlbnRpdHkuX2dldEVuY29kZXIoJ2RlcicpLnRyZWU7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fc2tpcERlZmF1bHQgPSBmdW5jdGlvbiBza2lwRGVmYXVsdChkYXRhQnVmZmVyLCByZXBvcnRlciwgcGFyZW50KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgdmFyIGk7XG4gIGlmIChzdGF0ZVsnZGVmYXVsdCddID09PSBudWxsKVxuICAgIHJldHVybiBmYWxzZTtcblxuICB2YXIgZGF0YSA9IGRhdGFCdWZmZXIuam9pbigpO1xuICBpZiAoc3RhdGUuZGVmYXVsdEJ1ZmZlciA9PT0gdW5kZWZpbmVkKVxuICAgIHN0YXRlLmRlZmF1bHRCdWZmZXIgPSB0aGlzLl9lbmNvZGVWYWx1ZShzdGF0ZVsnZGVmYXVsdCddLCByZXBvcnRlciwgcGFyZW50KS5qb2luKCk7XG5cbiAgaWYgKGRhdGEubGVuZ3RoICE9PSBzdGF0ZS5kZWZhdWx0QnVmZmVyLmxlbmd0aClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgZm9yIChpPTA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKVxuICAgIGlmIChkYXRhW2ldICE9PSBzdGF0ZS5kZWZhdWx0QnVmZmVyW2ldKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gIHJldHVybiB0cnVlO1xufTtcblxuLy8gVXRpbGl0eSBtZXRob2RzXG5cbmZ1bmN0aW9uIGVuY29kZVRhZyh0YWcsIHByaW1pdGl2ZSwgY2xzLCByZXBvcnRlcikge1xuICB2YXIgcmVzO1xuXG4gIGlmICh0YWcgPT09ICdzZXFvZicpXG4gICAgdGFnID0gJ3NlcSc7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ3NldG9mJylcbiAgICB0YWcgPSAnc2V0JztcblxuICBpZiAoZGVyLnRhZ0J5TmFtZS5oYXNPd25Qcm9wZXJ0eSh0YWcpKVxuICAgIHJlcyA9IGRlci50YWdCeU5hbWVbdGFnXTtcbiAgZWxzZSBpZiAodHlwZW9mIHRhZyA9PT0gJ251bWJlcicgJiYgKHRhZyB8IDApID09PSB0YWcpXG4gICAgcmVzID0gdGFnO1xuICBlbHNlXG4gICAgcmV0dXJuIHJlcG9ydGVyLmVycm9yKCdVbmtub3duIHRhZzogJyArIHRhZyk7XG5cbiAgaWYgKHJlcyA+PSAweDFmKVxuICAgIHJldHVybiByZXBvcnRlci5lcnJvcignTXVsdGktb2N0ZXQgdGFnIGVuY29kaW5nIHVuc3VwcG9ydGVkJyk7XG5cbiAgaWYgKCFwcmltaXRpdmUpXG4gICAgcmVzIHw9IDB4MjA7XG5cbiAgcmVzIHw9IChkZXIudGFnQ2xhc3NCeU5hbWVbY2xzIHx8ICd1bml2ZXJzYWwnXSA8PCA2KTtcblxuICByZXR1cm4gcmVzO1xufVxuIiwidmFyIGVuY29kZXJzID0gZXhwb3J0cztcblxuZW5jb2RlcnMuZGVyID0gcmVxdWlyZSgnLi9kZXInKTtcbmVuY29kZXJzLnBlbSA9IHJlcXVpcmUoJy4vcGVtJyk7XG4iLCJ2YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcblxudmFyIGFzbjEgPSByZXF1aXJlKCcuLi8uLi9hc24xJyk7XG52YXIgREVSRW5jb2RlciA9IHJlcXVpcmUoJy4vZGVyJyk7XG5cbmZ1bmN0aW9uIFBFTUVuY29kZXIoZW50aXR5KSB7XG4gIERFUkVuY29kZXIuY2FsbCh0aGlzLCBlbnRpdHkpO1xuICB0aGlzLmVuYyA9ICdwZW0nO1xufTtcbmluaGVyaXRzKFBFTUVuY29kZXIsIERFUkVuY29kZXIpO1xubW9kdWxlLmV4cG9ydHMgPSBQRU1FbmNvZGVyO1xuXG5QRU1FbmNvZGVyLnByb3RvdHlwZS5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUoZGF0YSwgb3B0aW9ucykge1xuICB2YXIgYnVmID0gREVSRW5jb2Rlci5wcm90b3R5cGUuZW5jb2RlLmNhbGwodGhpcywgZGF0YSk7XG5cbiAgdmFyIHAgPSBidWYudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICB2YXIgb3V0ID0gWyAnLS0tLS1CRUdJTiAnICsgb3B0aW9ucy5sYWJlbCArICctLS0tLScgXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwLmxlbmd0aDsgaSArPSA2NClcbiAgICBvdXQucHVzaChwLnNsaWNlKGksIGkgKyA2NCkpO1xuICBvdXQucHVzaCgnLS0tLS1FTkQgJyArIG9wdGlvbnMubGFiZWwgKyAnLS0tLS0nKTtcbiAgcmV0dXJuIG91dC5qb2luKCdcXG4nKTtcbn07XG4iLCIvLyBiYXNlZCBvbiB0aGUgYWVzIGltcGxpbWVudGF0aW9uIGluIHRyaXBsZSBzZWNcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9rZXliYXNlL3RyaXBsZXNlY1xuXG4vLyB3aGljaCBpcyBpbiB0dXJuIGJhc2VkIG9uIHRoZSBvbmUgZnJvbSBjcnlwdG8tanNcbi8vIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzL1xuXG52YXIgdWludF9tYXggPSBNYXRoLnBvdygyLCAzMilcbmZ1bmN0aW9uIGZpeHVwX3VpbnQzMiAoeCkge1xuICB2YXIgcmV0LCB4X3Bvc1xuICByZXQgPSB4ID4gdWludF9tYXggfHwgeCA8IDAgPyAoeF9wb3MgPSBNYXRoLmFicyh4KSAlIHVpbnRfbWF4LCB4IDwgMCA/IHVpbnRfbWF4IC0geF9wb3MgOiB4X3BvcykgOiB4XG4gIHJldHVybiByZXRcbn1cbmZ1bmN0aW9uIHNjcnViX3ZlYyAodikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHYubGVuZ3RoOyB2KyspIHtcbiAgICB2W2ldID0gMFxuICB9XG4gIHJldHVybiBmYWxzZVxufVxuXG5mdW5jdGlvbiBHbG9iYWwgKCkge1xuICB0aGlzLlNCT1ggPSBbXVxuICB0aGlzLklOVl9TQk9YID0gW11cbiAgdGhpcy5TVUJfTUlYID0gW1tdLCBbXSwgW10sIFtdXVxuICB0aGlzLklOVl9TVUJfTUlYID0gW1tdLCBbXSwgW10sIFtdXVxuICB0aGlzLmluaXQoKVxuICB0aGlzLlJDT04gPSBbMHgwMCwgMHgwMSwgMHgwMiwgMHgwNCwgMHgwOCwgMHgxMCwgMHgyMCwgMHg0MCwgMHg4MCwgMHgxYiwgMHgzNl1cbn1cblxuR2xvYmFsLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgZCwgaSwgc3gsIHQsIHgsIHgyLCB4NCwgeDgsIHhpLCBfaVxuICBkID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgX2ksIF9yZXN1bHRzXG4gICAgX3Jlc3VsdHMgPSBbXVxuICAgIGZvciAoaSA9IF9pID0gMDsgX2kgPCAyNTY7IGkgPSArK19pKSB7XG4gICAgICBpZiAoaSA8IDEyOCkge1xuICAgICAgICBfcmVzdWx0cy5wdXNoKGkgPDwgMSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIF9yZXN1bHRzLnB1c2goKGkgPDwgMSkgXiAweDExYilcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIF9yZXN1bHRzXG4gIH0pKClcbiAgeCA9IDBcbiAgeGkgPSAwXG4gIGZvciAoaSA9IF9pID0gMDsgX2kgPCAyNTY7IGkgPSArK19pKSB7XG4gICAgc3ggPSB4aSBeICh4aSA8PCAxKSBeICh4aSA8PCAyKSBeICh4aSA8PCAzKSBeICh4aSA8PCA0KVxuICAgIHN4ID0gKHN4ID4+PiA4KSBeIChzeCAmIDB4ZmYpIF4gMHg2M1xuICAgIHRoaXMuU0JPWFt4XSA9IHN4XG4gICAgdGhpcy5JTlZfU0JPWFtzeF0gPSB4XG4gICAgeDIgPSBkW3hdXG4gICAgeDQgPSBkW3gyXVxuICAgIHg4ID0gZFt4NF1cbiAgICB0ID0gKGRbc3hdICogMHgxMDEpIF4gKHN4ICogMHgxMDEwMTAwKVxuICAgIHRoaXMuU1VCX01JWFswXVt4XSA9ICh0IDw8IDI0KSB8ICh0ID4+PiA4KVxuICAgIHRoaXMuU1VCX01JWFsxXVt4XSA9ICh0IDw8IDE2KSB8ICh0ID4+PiAxNilcbiAgICB0aGlzLlNVQl9NSVhbMl1beF0gPSAodCA8PCA4KSB8ICh0ID4+PiAyNClcbiAgICB0aGlzLlNVQl9NSVhbM11beF0gPSB0XG4gICAgdCA9ICh4OCAqIDB4MTAxMDEwMSkgXiAoeDQgKiAweDEwMDAxKSBeICh4MiAqIDB4MTAxKSBeICh4ICogMHgxMDEwMTAwKVxuICAgIHRoaXMuSU5WX1NVQl9NSVhbMF1bc3hdID0gKHQgPDwgMjQpIHwgKHQgPj4+IDgpXG4gICAgdGhpcy5JTlZfU1VCX01JWFsxXVtzeF0gPSAodCA8PCAxNikgfCAodCA+Pj4gMTYpXG4gICAgdGhpcy5JTlZfU1VCX01JWFsyXVtzeF0gPSAodCA8PCA4KSB8ICh0ID4+PiAyNClcbiAgICB0aGlzLklOVl9TVUJfTUlYWzNdW3N4XSA9IHRcbiAgICBpZiAoeCA9PT0gMCkge1xuICAgICAgeCA9IHhpID0gMVxuICAgIH0gZWxzZSB7XG4gICAgICB4ID0geDIgXiBkW2RbZFt4OCBeIHgyXV1dXG4gICAgICB4aSBePSBkW2RbeGldXVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG52YXIgRyA9IG5ldyBHbG9iYWwoKVxuXG5BRVMuYmxvY2tTaXplID0gNCAqIDRcblxuQUVTLnByb3RvdHlwZS5ibG9ja1NpemUgPSBBRVMuYmxvY2tTaXplXG5cbkFFUy5rZXlTaXplID0gMjU2IC8gOFxuXG5BRVMucHJvdG90eXBlLmtleVNpemUgPSBBRVMua2V5U2l6ZVxuXG5mdW5jdGlvbiBidWZmZXJUb0FycmF5IChidWYpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGggLyA0XG4gIHZhciBvdXQgPSBuZXcgQXJyYXkobGVuKVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXRbaV0gPSBidWYucmVhZFVJbnQzMkJFKGkgKiA0KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbmZ1bmN0aW9uIEFFUyAoa2V5KSB7XG4gIHRoaXMuX2tleSA9IGJ1ZmZlclRvQXJyYXkoa2V5KVxuICB0aGlzLl9kb1Jlc2V0KClcbn1cblxuQUVTLnByb3RvdHlwZS5fZG9SZXNldCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGludktzUm93LCBrZXlTaXplLCBrZXlXb3Jkcywga3NSb3csIGtzUm93cywgdFxuICBrZXlXb3JkcyA9IHRoaXMuX2tleVxuICBrZXlTaXplID0ga2V5V29yZHMubGVuZ3RoXG4gIHRoaXMuX25Sb3VuZHMgPSBrZXlTaXplICsgNlxuICBrc1Jvd3MgPSAodGhpcy5fblJvdW5kcyArIDEpICogNFxuICB0aGlzLl9rZXlTY2hlZHVsZSA9IFtdXG4gIGZvciAoa3NSb3cgPSAwOyBrc1JvdyA8IGtzUm93czsga3NSb3crKykge1xuICAgIHRoaXMuX2tleVNjaGVkdWxlW2tzUm93XSA9IGtzUm93IDwga2V5U2l6ZSA/IGtleVdvcmRzW2tzUm93XSA6ICh0ID0gdGhpcy5fa2V5U2NoZWR1bGVba3NSb3cgLSAxXSwgKGtzUm93ICUga2V5U2l6ZSkgPT09IDAgPyAodCA9ICh0IDw8IDgpIHwgKHQgPj4+IDI0KSwgdCA9IChHLlNCT1hbdCA+Pj4gMjRdIDw8IDI0KSB8IChHLlNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChHLlNCT1hbKHQgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBHLlNCT1hbdCAmIDB4ZmZdLCB0IF49IEcuUkNPTlsoa3NSb3cgLyBrZXlTaXplKSB8IDBdIDw8IDI0KSA6IGtleVNpemUgPiA2ICYmIGtzUm93ICUga2V5U2l6ZSA9PT0gNCA/IHQgPSAoRy5TQk9YW3QgPj4+IDI0XSA8PCAyNCkgfCAoRy5TQk9YWyh0ID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoRy5TQk9YWyh0ID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgRy5TQk9YW3QgJiAweGZmXSA6IHZvaWQgMCwgdGhpcy5fa2V5U2NoZWR1bGVba3NSb3cgLSBrZXlTaXplXSBeIHQpXG4gIH1cbiAgdGhpcy5faW52S2V5U2NoZWR1bGUgPSBbXVxuICBmb3IgKGludktzUm93ID0gMDsgaW52S3NSb3cgPCBrc1Jvd3M7IGludktzUm93KyspIHtcbiAgICBrc1JvdyA9IGtzUm93cyAtIGludktzUm93XG4gICAgdCA9IHRoaXMuX2tleVNjaGVkdWxlW2tzUm93IC0gKGludktzUm93ICUgNCA/IDAgOiA0KV1cbiAgICB0aGlzLl9pbnZLZXlTY2hlZHVsZVtpbnZLc1Jvd10gPSBpbnZLc1JvdyA8IDQgfHwga3NSb3cgPD0gNCA/IHQgOiBHLklOVl9TVUJfTUlYWzBdW0cuU0JPWFt0ID4+PiAyNF1dIF4gRy5JTlZfU1VCX01JWFsxXVtHLlNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdXSBeIEcuSU5WX1NVQl9NSVhbMl1bRy5TQk9YWyh0ID4+PiA4KSAmIDB4ZmZdXSBeIEcuSU5WX1NVQl9NSVhbM11bRy5TQk9YW3QgJiAweGZmXV1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG5BRVMucHJvdG90eXBlLmVuY3J5cHRCbG9jayA9IGZ1bmN0aW9uIChNKSB7XG4gIE0gPSBidWZmZXJUb0FycmF5KG5ldyBCdWZmZXIoTSkpXG4gIHZhciBvdXQgPSB0aGlzLl9kb0NyeXB0QmxvY2soTSwgdGhpcy5fa2V5U2NoZWR1bGUsIEcuU1VCX01JWCwgRy5TQk9YKVxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcigxNilcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzBdLCAwKVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMV0sIDQpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsyXSwgOClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzNdLCAxMilcbiAgcmV0dXJuIGJ1ZlxufVxuXG5BRVMucHJvdG90eXBlLmRlY3J5cHRCbG9jayA9IGZ1bmN0aW9uIChNKSB7XG4gIE0gPSBidWZmZXJUb0FycmF5KG5ldyBCdWZmZXIoTSkpXG4gIHZhciB0ZW1wID0gW01bM10sIE1bMV1dXG4gIE1bMV0gPSB0ZW1wWzBdXG4gIE1bM10gPSB0ZW1wWzFdXG4gIHZhciBvdXQgPSB0aGlzLl9kb0NyeXB0QmxvY2soTSwgdGhpcy5faW52S2V5U2NoZWR1bGUsIEcuSU5WX1NVQl9NSVgsIEcuSU5WX1NCT1gpXG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKDE2KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMF0sIDApXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFszXSwgNClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzJdLCA4KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMV0sIDEyKVxuICByZXR1cm4gYnVmXG59XG5cbkFFUy5wcm90b3R5cGUuc2NydWIgPSBmdW5jdGlvbiAoKSB7XG4gIHNjcnViX3ZlYyh0aGlzLl9rZXlTY2hlZHVsZSlcbiAgc2NydWJfdmVjKHRoaXMuX2ludktleVNjaGVkdWxlKVxuICBzY3J1Yl92ZWModGhpcy5fa2V5KVxufVxuXG5BRVMucHJvdG90eXBlLl9kb0NyeXB0QmxvY2sgPSBmdW5jdGlvbiAoTSwga2V5U2NoZWR1bGUsIFNVQl9NSVgsIFNCT1gpIHtcbiAgdmFyIGtzUm93LCBzMCwgczEsIHMyLCBzMywgdDAsIHQxLCB0MiwgdDNcblxuICBzMCA9IE1bMF0gXiBrZXlTY2hlZHVsZVswXVxuICBzMSA9IE1bMV0gXiBrZXlTY2hlZHVsZVsxXVxuICBzMiA9IE1bMl0gXiBrZXlTY2hlZHVsZVsyXVxuICBzMyA9IE1bM10gXiBrZXlTY2hlZHVsZVszXVxuICBrc1JvdyA9IDRcbiAgZm9yICh2YXIgcm91bmQgPSAxOyByb3VuZCA8IHRoaXMuX25Sb3VuZHM7IHJvdW5kKyspIHtcbiAgICB0MCA9IFNVQl9NSVhbMF1bczAgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMxID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMyID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMyAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MSA9IFNVQl9NSVhbMF1bczEgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMyID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMzID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMCAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MiA9IFNVQl9NSVhbMF1bczIgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMzID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMwID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMSAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MyA9IFNVQl9NSVhbMF1bczMgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMwID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMxID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMiAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICBzMCA9IHQwXG4gICAgczEgPSB0MVxuICAgIHMyID0gdDJcbiAgICBzMyA9IHQzXG4gIH1cbiAgdDAgPSAoKFNCT1hbczAgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczEgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMiA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczMgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICB0MSA9ICgoU0JPWFtzMSA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMiA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMzID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMCAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gIHQyID0gKChTQk9YW3MyID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMzID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczAgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MxICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgdDMgPSAoKFNCT1hbczMgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczAgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMSA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczIgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICByZXR1cm4gW1xuICAgIGZpeHVwX3VpbnQzMih0MCksXG4gICAgZml4dXBfdWludDMyKHQxKSxcbiAgICBmaXh1cF91aW50MzIodDIpLFxuICAgIGZpeHVwX3VpbnQzMih0MylcbiAgXVxufVxuXG5leHBvcnRzLkFFUyA9IEFFU1xuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgR0hBU0ggPSByZXF1aXJlKCcuL2doYXNoJylcbnZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcbmluaGVyaXRzKFN0cmVhbUNpcGhlciwgVHJhbnNmb3JtKVxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW1DaXBoZXJcblxuZnVuY3Rpb24gU3RyZWFtQ2lwaGVyIChtb2RlLCBrZXksIGl2LCBkZWNyeXB0KSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTdHJlYW1DaXBoZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBTdHJlYW1DaXBoZXIobW9kZSwga2V5LCBpdilcbiAgfVxuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuICB0aGlzLl9maW5JRCA9IEJ1ZmZlci5jb25jYXQoW2l2LCBuZXcgQnVmZmVyKFswLCAwLCAwLCAxXSldKVxuICBpdiA9IEJ1ZmZlci5jb25jYXQoW2l2LCBuZXcgQnVmZmVyKFswLCAwLCAwLCAyXSldKVxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHRoaXMuX3ByZXYgPSBuZXcgQnVmZmVyKGl2Lmxlbmd0aClcbiAgdGhpcy5fY2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxuICB0aGlzLl9zZWNDYWNoZSA9IG5ldyBCdWZmZXIoJycpXG4gIHRoaXMuX2RlY3J5cHQgPSBkZWNyeXB0XG4gIHRoaXMuX2FsZW4gPSAwXG4gIHRoaXMuX2xlbiA9IDBcbiAgaXYuY29weSh0aGlzLl9wcmV2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxuICB2YXIgaCA9IG5ldyBCdWZmZXIoNClcbiAgaC5maWxsKDApXG4gIHRoaXMuX2doYXNoID0gbmV3IEdIQVNIKHRoaXMuX2NpcGhlci5lbmNyeXB0QmxvY2soaCkpXG4gIHRoaXMuX2F1dGhUYWcgPSBudWxsXG4gIHRoaXMuX2NhbGxlZCA9IGZhbHNlXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgaWYgKCF0aGlzLl9jYWxsZWQgJiYgdGhpcy5fYWxlbikge1xuICAgIHZhciBydW1wID0gMTYgLSAodGhpcy5fYWxlbiAlIDE2KVxuICAgIGlmIChydW1wIDwgMTYpIHtcbiAgICAgIHJ1bXAgPSBuZXcgQnVmZmVyKHJ1bXApXG4gICAgICBydW1wLmZpbGwoMClcbiAgICAgIHRoaXMuX2doYXNoLnVwZGF0ZShydW1wKVxuICAgIH1cbiAgfVxuICB0aGlzLl9jYWxsZWQgPSB0cnVlXG4gIHZhciBvdXQgPSB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmspXG4gIGlmICh0aGlzLl9kZWNyeXB0KSB7XG4gICAgdGhpcy5fZ2hhc2gudXBkYXRlKGNodW5rKVxuICB9IGVsc2Uge1xuICAgIHRoaXMuX2doYXNoLnVwZGF0ZShvdXQpXG4gIH1cbiAgdGhpcy5fbGVuICs9IGNodW5rLmxlbmd0aFxuICByZXR1cm4gb3V0XG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuX2RlY3J5cHQgJiYgIXRoaXMuX2F1dGhUYWcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIHN0YXRlIG9yIHVuYWJsZSB0byBhdXRoZW50aWNhdGUgZGF0YScpXG4gIH1cbiAgdmFyIHRhZyA9IHhvcih0aGlzLl9naGFzaC5maW5hbCh0aGlzLl9hbGVuICogOCwgdGhpcy5fbGVuICogOCksIHRoaXMuX2NpcGhlci5lbmNyeXB0QmxvY2sodGhpcy5fZmluSUQpKVxuICBpZiAodGhpcy5fZGVjcnlwdCkge1xuICAgIGlmICh4b3JUZXN0KHRhZywgdGhpcy5fYXV0aFRhZykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgc3RhdGUgb3IgdW5hYmxlIHRvIGF1dGhlbnRpY2F0ZSBkYXRhJylcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fYXV0aFRhZyA9IHRhZ1xuICB9XG4gIHRoaXMuX2NpcGhlci5zY3J1YigpXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiBnZXRBdXRoVGFnICgpIHtcbiAgaWYgKCF0aGlzLl9kZWNyeXB0ICYmIEJ1ZmZlci5pc0J1ZmZlcih0aGlzLl9hdXRoVGFnKSkge1xuICAgIHJldHVybiB0aGlzLl9hdXRoVGFnXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG4gIH1cbn1cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuc2V0QXV0aFRhZyA9IGZ1bmN0aW9uIHNldEF1dGhUYWcgKHRhZykge1xuICBpZiAodGhpcy5fZGVjcnlwdCkge1xuICAgIHRoaXMuX2F1dGhUYWcgPSB0YWdcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0F0dGVtcHRpbmcgdG8gc2V0IGF1dGggdGFnIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbiAgfVxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5zZXRBQUQgPSBmdW5jdGlvbiBzZXRBQUQgKGJ1Zikge1xuICBpZiAoIXRoaXMuX2NhbGxlZCkge1xuICAgIHRoaXMuX2doYXNoLnVwZGF0ZShidWYpXG4gICAgdGhpcy5fYWxlbiArPSBidWYubGVuZ3RoXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIHNldCBBQUQgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxuICB9XG59XG5mdW5jdGlvbiB4b3JUZXN0IChhLCBiKSB7XG4gIHZhciBvdXQgPSAwXG4gIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHtcbiAgICBvdXQrK1xuICB9XG4gIHZhciBsZW4gPSBNYXRoLm1pbihhLmxlbmd0aCwgYi5sZW5ndGgpXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dCArPSAoYVtpXSBeIGJbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgbW9kZXMgPSByZXF1aXJlKCcuL21vZGVzJylcbnZhciBTdHJlYW1DaXBoZXIgPSByZXF1aXJlKCcuL3N0cmVhbUNpcGhlcicpXG52YXIgQXV0aENpcGhlciA9IHJlcXVpcmUoJy4vYXV0aENpcGhlcicpXG52YXIgZWJ0ayA9IHJlcXVpcmUoJ2V2cF9ieXRlc3Rva2V5JylcblxuaW5oZXJpdHMoRGVjaXBoZXIsIFRyYW5zZm9ybSlcbmZ1bmN0aW9uIERlY2lwaGVyIChtb2RlLCBrZXksIGl2KSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBEZWNpcGhlcikpIHtcbiAgICByZXR1cm4gbmV3IERlY2lwaGVyKG1vZGUsIGtleSwgaXYpXG4gIH1cbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5fY2FjaGUgPSBuZXcgU3BsaXR0ZXIoKVxuICB0aGlzLl9sYXN0ID0gdm9pZCAwXG4gIHRoaXMuX2NpcGhlciA9IG5ldyBhZXMuQUVTKGtleSlcbiAgdGhpcy5fcHJldiA9IG5ldyBCdWZmZXIoaXYubGVuZ3RoKVxuICBpdi5jb3B5KHRoaXMuX3ByZXYpXG4gIHRoaXMuX21vZGUgPSBtb2RlXG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gdHJ1ZVxufVxuRGVjaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB0aGlzLl9jYWNoZS5hZGQoZGF0YSlcbiAgdmFyIGNodW5rXG4gIHZhciB0aGluZ1xuICB2YXIgb3V0ID0gW11cbiAgd2hpbGUgKChjaHVuayA9IHRoaXMuX2NhY2hlLmdldCh0aGlzLl9hdXRvcGFkZGluZykpKSB7XG4gICAgdGhpbmcgPSB0aGlzLl9tb2RlLmRlY3J5cHQodGhpcywgY2h1bmspXG4gICAgb3V0LnB1c2godGhpbmcpXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5jb25jYXQob3V0KVxufVxuRGVjaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNodW5rID0gdGhpcy5fY2FjaGUuZmx1c2goKVxuICBpZiAodGhpcy5fYXV0b3BhZGRpbmcpIHtcbiAgICByZXR1cm4gdW5wYWQodGhpcy5fbW9kZS5kZWNyeXB0KHRoaXMsIGNodW5rKSlcbiAgfSBlbHNlIGlmIChjaHVuaykge1xuICAgIHRocm93IG5ldyBFcnJvcignZGF0YSBub3QgbXVsdGlwbGUgb2YgYmxvY2sgbGVuZ3RoJylcbiAgfVxufVxuRGVjaXBoZXIucHJvdG90eXBlLnNldEF1dG9QYWRkaW5nID0gZnVuY3Rpb24gKHNldFRvKSB7XG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gISFzZXRUb1xuICByZXR1cm4gdGhpc1xufVxuZnVuY3Rpb24gU3BsaXR0ZXIgKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3BsaXR0ZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBTcGxpdHRlcigpXG4gIH1cbiAgdGhpcy5jYWNoZSA9IG5ldyBCdWZmZXIoJycpXG59XG5TcGxpdHRlci5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIGRhdGFdKVxufVxuXG5TcGxpdHRlci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGF1dG9QYWRkaW5nKSB7XG4gIHZhciBvdXRcbiAgaWYgKGF1dG9QYWRkaW5nKSB7XG4gICAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoID4gMTYpIHtcbiAgICAgIG91dCA9IHRoaXMuY2FjaGUuc2xpY2UoMCwgMTYpXG4gICAgICB0aGlzLmNhY2hlID0gdGhpcy5jYWNoZS5zbGljZSgxNilcbiAgICAgIHJldHVybiBvdXRcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoID49IDE2KSB7XG4gICAgICBvdXQgPSB0aGlzLmNhY2hlLnNsaWNlKDAsIDE2KVxuICAgICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgICByZXR1cm4gb3V0XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsXG59XG5TcGxpdHRlci5wcm90b3R5cGUuZmx1c2ggPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmNhY2hlLmxlbmd0aCkge1xuICAgIHJldHVybiB0aGlzLmNhY2hlXG4gIH1cbn1cbmZ1bmN0aW9uIHVucGFkIChsYXN0KSB7XG4gIHZhciBwYWRkZWQgPSBsYXN0WzE1XVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBwYWRkZWQpIHtcbiAgICBpZiAobGFzdFsoaSArICgxNiAtIHBhZGRlZCkpXSAhPT0gcGFkZGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VuYWJsZSB0byBkZWNyeXB0IGRhdGEnKVxuICAgIH1cbiAgfVxuICBpZiAocGFkZGVkID09PSAxNikge1xuICAgIHJldHVyblxuICB9XG4gIHJldHVybiBsYXN0LnNsaWNlKDAsIDE2IC0gcGFkZGVkKVxufVxuXG52YXIgbW9kZWxpc3QgPSB7XG4gIEVDQjogcmVxdWlyZSgnLi9tb2Rlcy9lY2InKSxcbiAgQ0JDOiByZXF1aXJlKCcuL21vZGVzL2NiYycpLFxuICBDRkI6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiJyksXG4gIENGQjg6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiOCcpLFxuICBDRkIxOiByZXF1aXJlKCcuL21vZGVzL2NmYjEnKSxcbiAgT0ZCOiByZXF1aXJlKCcuL21vZGVzL29mYicpLFxuICBDVFI6IHJlcXVpcmUoJy4vbW9kZXMvY3RyJyksXG4gIEdDTTogcmVxdWlyZSgnLi9tb2Rlcy9jdHInKVxufVxuXG5mdW5jdGlvbiBjcmVhdGVEZWNpcGhlcml2IChzdWl0ZSwgcGFzc3dvcmQsIGl2KSB7XG4gIHZhciBjb25maWcgPSBtb2Rlc1tzdWl0ZS50b0xvd2VyQ2FzZSgpXVxuICBpZiAoIWNvbmZpZykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgaWYgKHR5cGVvZiBpdiA9PT0gJ3N0cmluZycpIHtcbiAgICBpdiA9IG5ldyBCdWZmZXIoaXYpXG4gIH1cbiAgaWYgKHR5cGVvZiBwYXNzd29yZCA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXNzd29yZCA9IG5ldyBCdWZmZXIocGFzc3dvcmQpXG4gIH1cbiAgaWYgKHBhc3N3b3JkLmxlbmd0aCAhPT0gY29uZmlnLmtleSAvIDgpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGtleSBsZW5ndGggJyArIHBhc3N3b3JkLmxlbmd0aClcbiAgfVxuICBpZiAoaXYubGVuZ3RoICE9PSBjb25maWcuaXYpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGl2IGxlbmd0aCAnICsgaXYubGVuZ3RoKVxuICB9XG4gIGlmIChjb25maWcudHlwZSA9PT0gJ3N0cmVhbScpIHtcbiAgICByZXR1cm4gbmV3IFN0cmVhbUNpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdiwgdHJ1ZSlcbiAgfSBlbHNlIGlmIChjb25maWcudHlwZSA9PT0gJ2F1dGgnKSB7XG4gICAgcmV0dXJuIG5ldyBBdXRoQ2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2LCB0cnVlKVxuICB9XG4gIHJldHVybiBuZXcgRGVjaXBoZXIobW9kZWxpc3RbY29uZmlnLm1vZGVdLCBwYXNzd29yZCwgaXYpXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZURlY2lwaGVyIChzdWl0ZSwgcGFzc3dvcmQpIHtcbiAgdmFyIGNvbmZpZyA9IG1vZGVzW3N1aXRlLnRvTG93ZXJDYXNlKCldXG4gIGlmICghY29uZmlnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBzdWl0ZSB0eXBlJylcbiAgfVxuICB2YXIga2V5cyA9IGVidGsocGFzc3dvcmQsIGZhbHNlLCBjb25maWcua2V5LCBjb25maWcuaXYpXG4gIHJldHVybiBjcmVhdGVEZWNpcGhlcml2KHN1aXRlLCBrZXlzLmtleSwga2V5cy5pdilcbn1cbmV4cG9ydHMuY3JlYXRlRGVjaXBoZXIgPSBjcmVhdGVEZWNpcGhlclxuZXhwb3J0cy5jcmVhdGVEZWNpcGhlcml2ID0gY3JlYXRlRGVjaXBoZXJpdlxuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgbW9kZXMgPSByZXF1aXJlKCcuL21vZGVzJylcbnZhciBlYnRrID0gcmVxdWlyZSgnZXZwX2J5dGVzdG9rZXknKVxudmFyIFN0cmVhbUNpcGhlciA9IHJlcXVpcmUoJy4vc3RyZWFtQ2lwaGVyJylcbnZhciBBdXRoQ2lwaGVyID0gcmVxdWlyZSgnLi9hdXRoQ2lwaGVyJylcbmluaGVyaXRzKENpcGhlciwgVHJhbnNmb3JtKVxuZnVuY3Rpb24gQ2lwaGVyIChtb2RlLCBrZXksIGl2KSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBDaXBoZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBDaXBoZXIobW9kZSwga2V5LCBpdilcbiAgfVxuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuICB0aGlzLl9jYWNoZSA9IG5ldyBTcGxpdHRlcigpXG4gIHRoaXMuX2NpcGhlciA9IG5ldyBhZXMuQUVTKGtleSlcbiAgdGhpcy5fcHJldiA9IG5ldyBCdWZmZXIoaXYubGVuZ3RoKVxuICBpdi5jb3B5KHRoaXMuX3ByZXYpXG4gIHRoaXMuX21vZGUgPSBtb2RlXG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gdHJ1ZVxufVxuQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5fY2FjaGUuYWRkKGRhdGEpXG4gIHZhciBjaHVua1xuICB2YXIgdGhpbmdcbiAgdmFyIG91dCA9IFtdXG4gIHdoaWxlICgoY2h1bmsgPSB0aGlzLl9jYWNoZS5nZXQoKSkpIHtcbiAgICB0aGluZyA9IHRoaXMuX21vZGUuZW5jcnlwdCh0aGlzLCBjaHVuaylcbiAgICBvdXQucHVzaCh0aGluZylcbiAgfVxuICByZXR1cm4gQnVmZmVyLmNvbmNhdChvdXQpXG59XG5DaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNodW5rID0gdGhpcy5fY2FjaGUuZmx1c2goKVxuICBpZiAodGhpcy5fYXV0b3BhZGRpbmcpIHtcbiAgICBjaHVuayA9IHRoaXMuX21vZGUuZW5jcnlwdCh0aGlzLCBjaHVuaylcbiAgICB0aGlzLl9jaXBoZXIuc2NydWIoKVxuICAgIHJldHVybiBjaHVua1xuICB9IGVsc2UgaWYgKGNodW5rLnRvU3RyaW5nKCdoZXgnKSAhPT0gJzEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwJykge1xuICAgIHRoaXMuX2NpcGhlci5zY3J1YigpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhIG5vdCBtdWx0aXBsZSBvZiBibG9jayBsZW5ndGgnKVxuICB9XG59XG5DaXBoZXIucHJvdG90eXBlLnNldEF1dG9QYWRkaW5nID0gZnVuY3Rpb24gKHNldFRvKSB7XG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gISFzZXRUb1xuICByZXR1cm4gdGhpc1xufVxuXG5mdW5jdGlvbiBTcGxpdHRlciAoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTcGxpdHRlcikpIHtcbiAgICByZXR1cm4gbmV3IFNwbGl0dGVyKClcbiAgfVxuICB0aGlzLmNhY2hlID0gbmV3IEJ1ZmZlcignJylcbn1cblNwbGl0dGVyLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB0aGlzLmNhY2hlID0gQnVmZmVyLmNvbmNhdChbdGhpcy5jYWNoZSwgZGF0YV0pXG59XG5cblNwbGl0dGVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmNhY2hlLmxlbmd0aCA+IDE1KSB7XG4gICAgdmFyIG91dCA9IHRoaXMuY2FjaGUuc2xpY2UoMCwgMTYpXG4gICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgcmV0dXJuIG91dFxuICB9XG4gIHJldHVybiBudWxsXG59XG5TcGxpdHRlci5wcm90b3R5cGUuZmx1c2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBsZW4gPSAxNiAtIHRoaXMuY2FjaGUubGVuZ3RoXG4gIHZhciBwYWRCdWZmID0gbmV3IEJ1ZmZlcihsZW4pXG5cbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgcGFkQnVmZi53cml0ZVVJbnQ4KGxlbiwgaSlcbiAgfVxuICB2YXIgb3V0ID0gQnVmZmVyLmNvbmNhdChbdGhpcy5jYWNoZSwgcGFkQnVmZl0pXG4gIHJldHVybiBvdXRcbn1cbnZhciBtb2RlbGlzdCA9IHtcbiAgRUNCOiByZXF1aXJlKCcuL21vZGVzL2VjYicpLFxuICBDQkM6IHJlcXVpcmUoJy4vbW9kZXMvY2JjJyksXG4gIENGQjogcmVxdWlyZSgnLi9tb2Rlcy9jZmInKSxcbiAgQ0ZCODogcmVxdWlyZSgnLi9tb2Rlcy9jZmI4JyksXG4gIENGQjE6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiMScpLFxuICBPRkI6IHJlcXVpcmUoJy4vbW9kZXMvb2ZiJyksXG4gIENUUjogcmVxdWlyZSgnLi9tb2Rlcy9jdHInKSxcbiAgR0NNOiByZXF1aXJlKCcuL21vZGVzL2N0cicpXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNpcGhlcml2IChzdWl0ZSwgcGFzc3dvcmQsIGl2KSB7XG4gIHZhciBjb25maWcgPSBtb2Rlc1tzdWl0ZS50b0xvd2VyQ2FzZSgpXVxuICBpZiAoIWNvbmZpZykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgaWYgKHR5cGVvZiBpdiA9PT0gJ3N0cmluZycpIHtcbiAgICBpdiA9IG5ldyBCdWZmZXIoaXYpXG4gIH1cbiAgaWYgKHR5cGVvZiBwYXNzd29yZCA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXNzd29yZCA9IG5ldyBCdWZmZXIocGFzc3dvcmQpXG4gIH1cbiAgaWYgKHBhc3N3b3JkLmxlbmd0aCAhPT0gY29uZmlnLmtleSAvIDgpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGtleSBsZW5ndGggJyArIHBhc3N3b3JkLmxlbmd0aClcbiAgfVxuICBpZiAoaXYubGVuZ3RoICE9PSBjb25maWcuaXYpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGl2IGxlbmd0aCAnICsgaXYubGVuZ3RoKVxuICB9XG4gIGlmIChjb25maWcudHlwZSA9PT0gJ3N0cmVhbScpIHtcbiAgICByZXR1cm4gbmV3IFN0cmVhbUNpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdilcbiAgfSBlbHNlIGlmIChjb25maWcudHlwZSA9PT0gJ2F1dGgnKSB7XG4gICAgcmV0dXJuIG5ldyBBdXRoQ2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2KVxuICB9XG4gIHJldHVybiBuZXcgQ2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2KVxufVxuZnVuY3Rpb24gY3JlYXRlQ2lwaGVyIChzdWl0ZSwgcGFzc3dvcmQpIHtcbiAgdmFyIGNvbmZpZyA9IG1vZGVzW3N1aXRlLnRvTG93ZXJDYXNlKCldXG4gIGlmICghY29uZmlnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBzdWl0ZSB0eXBlJylcbiAgfVxuICB2YXIga2V5cyA9IGVidGsocGFzc3dvcmQsIGZhbHNlLCBjb25maWcua2V5LCBjb25maWcuaXYpXG4gIHJldHVybiBjcmVhdGVDaXBoZXJpdihzdWl0ZSwga2V5cy5rZXksIGtleXMuaXYpXG59XG5cbmV4cG9ydHMuY3JlYXRlQ2lwaGVyaXYgPSBjcmVhdGVDaXBoZXJpdlxuZXhwb3J0cy5jcmVhdGVDaXBoZXIgPSBjcmVhdGVDaXBoZXJcbiIsInZhciB6ZXJvcyA9IG5ldyBCdWZmZXIoMTYpXG56ZXJvcy5maWxsKDApXG5tb2R1bGUuZXhwb3J0cyA9IEdIQVNIXG5mdW5jdGlvbiBHSEFTSCAoa2V5KSB7XG4gIHRoaXMuaCA9IGtleVxuICB0aGlzLnN0YXRlID0gbmV3IEJ1ZmZlcigxNilcbiAgdGhpcy5zdGF0ZS5maWxsKDApXG4gIHRoaXMuY2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxufVxuLy8gZnJvbSBodHRwOi8vYml0d2lzZXNoaWZ0bGVmdC5naXRodWIuaW8vc2pjbC9kb2Mvc3ltYm9scy9zcmMvY29yZV9nY20uanMuaHRtbFxuLy8gYnkgSnVobyBWw6Row6QtSGVydHR1YVxuR0hBU0gucHJvdG90eXBlLmdoYXNoID0gZnVuY3Rpb24gKGJsb2NrKSB7XG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGJsb2NrLmxlbmd0aCkge1xuICAgIHRoaXMuc3RhdGVbaV0gXj0gYmxvY2tbaV1cbiAgfVxuICB0aGlzLl9tdWx0aXBseSgpXG59XG5cbkdIQVNILnByb3RvdHlwZS5fbXVsdGlwbHkgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBWaSA9IHRvQXJyYXkodGhpcy5oKVxuICB2YXIgWmkgPSBbMCwgMCwgMCwgMF1cbiAgdmFyIGosIHhpLCBsc2JfVmlcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgMTI4KSB7XG4gICAgeGkgPSAodGhpcy5zdGF0ZVt+fihpIC8gOCldICYgKDEgPDwgKDcgLSBpICUgOCkpKSAhPT0gMFxuICAgIGlmICh4aSkge1xuICAgICAgLy8gWl9pKzEgPSBaX2kgXiBWX2lcbiAgICAgIFppID0geG9yKFppLCBWaSlcbiAgICB9XG5cbiAgICAvLyBTdG9yZSB0aGUgdmFsdWUgb2YgTFNCKFZfaSlcbiAgICBsc2JfVmkgPSAoVmlbM10gJiAxKSAhPT0gMFxuXG4gICAgLy8gVl9pKzEgPSBWX2kgPj4gMVxuICAgIGZvciAoaiA9IDM7IGogPiAwOyBqLS0pIHtcbiAgICAgIFZpW2pdID0gKFZpW2pdID4+PiAxKSB8ICgoVmlbaiAtIDFdICYgMSkgPDwgMzEpXG4gICAgfVxuICAgIFZpWzBdID0gVmlbMF0gPj4+IDFcblxuICAgIC8vIElmIExTQihWX2kpIGlzIDEsIFZfaSsxID0gKFZfaSA+PiAxKSBeIFJcbiAgICBpZiAobHNiX1ZpKSB7XG4gICAgICBWaVswXSA9IFZpWzBdIF4gKDB4ZTEgPDwgMjQpXG4gICAgfVxuICB9XG4gIHRoaXMuc3RhdGUgPSBmcm9tQXJyYXkoWmkpXG59XG5HSEFTSC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGJ1Zikge1xuICB0aGlzLmNhY2hlID0gQnVmZmVyLmNvbmNhdChbdGhpcy5jYWNoZSwgYnVmXSlcbiAgdmFyIGNodW5rXG4gIHdoaWxlICh0aGlzLmNhY2hlLmxlbmd0aCA+PSAxNikge1xuICAgIGNodW5rID0gdGhpcy5jYWNoZS5zbGljZSgwLCAxNilcbiAgICB0aGlzLmNhY2hlID0gdGhpcy5jYWNoZS5zbGljZSgxNilcbiAgICB0aGlzLmdoYXNoKGNodW5rKVxuICB9XG59XG5HSEFTSC5wcm90b3R5cGUuZmluYWwgPSBmdW5jdGlvbiAoYWJsLCBibCkge1xuICBpZiAodGhpcy5jYWNoZS5sZW5ndGgpIHtcbiAgICB0aGlzLmdoYXNoKEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIHplcm9zXSwgMTYpKVxuICB9XG4gIHRoaXMuZ2hhc2goZnJvbUFycmF5KFtcbiAgICAwLCBhYmwsXG4gICAgMCwgYmxcbiAgXSkpXG4gIHJldHVybiB0aGlzLnN0YXRlXG59XG5cbmZ1bmN0aW9uIHRvQXJyYXkgKGJ1Zikge1xuICByZXR1cm4gW1xuICAgIGJ1Zi5yZWFkVUludDMyQkUoMCksXG4gICAgYnVmLnJlYWRVSW50MzJCRSg0KSxcbiAgICBidWYucmVhZFVJbnQzMkJFKDgpLFxuICAgIGJ1Zi5yZWFkVUludDMyQkUoMTIpXG4gIF1cbn1cbmZ1bmN0aW9uIGZyb21BcnJheSAob3V0KSB7XG4gIG91dCA9IG91dC5tYXAoZml4dXBfdWludDMyKVxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcigxNilcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzBdLCAwKVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMV0sIDQpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsyXSwgOClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzNdLCAxMilcbiAgcmV0dXJuIGJ1ZlxufVxudmFyIHVpbnRfbWF4ID0gTWF0aC5wb3coMiwgMzIpXG5mdW5jdGlvbiBmaXh1cF91aW50MzIgKHgpIHtcbiAgdmFyIHJldCwgeF9wb3NcbiAgcmV0ID0geCA+IHVpbnRfbWF4IHx8IHggPCAwID8gKHhfcG9zID0gTWF0aC5hYnMoeCkgJSB1aW50X21heCwgeCA8IDAgPyB1aW50X21heCAtIHhfcG9zIDogeF9wb3MpIDogeFxuICByZXR1cm4gcmV0XG59XG5mdW5jdGlvbiB4b3IgKGEsIGIpIHtcbiAgcmV0dXJuIFtcbiAgICBhWzBdIF4gYlswXSxcbiAgICBhWzFdIF4gYlsxXSxcbiAgICBhWzJdIF4gYlsyXSxcbiAgICBhWzNdIF4gYlszXVxuICBdXG59XG4iLCJ2YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG5cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBkYXRhLCBkZWNyeXB0KSB7XG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKCcnKVxuICB2YXIgbGVuXG5cbiAgd2hpbGUgKGRhdGEubGVuZ3RoKSB7XG4gICAgaWYgKHNlbGYuX2NhY2hlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gICAgICBzZWxmLl9wcmV2ID0gbmV3IEJ1ZmZlcignJylcbiAgICB9XG5cbiAgICBpZiAoc2VsZi5fY2FjaGUubGVuZ3RoIDw9IGRhdGEubGVuZ3RoKSB7XG4gICAgICBsZW4gPSBzZWxmLl9jYWNoZS5sZW5ndGhcbiAgICAgIG91dCA9IEJ1ZmZlci5jb25jYXQoW291dCwgZW5jcnlwdFN0YXJ0KHNlbGYsIGRhdGEuc2xpY2UoMCwgbGVuKSwgZGVjcnlwdCldKVxuICAgICAgZGF0YSA9IGRhdGEuc2xpY2UobGVuKVxuICAgIH0gZWxzZSB7XG4gICAgICBvdXQgPSBCdWZmZXIuY29uY2F0KFtvdXQsIGVuY3J5cHRTdGFydChzZWxmLCBkYXRhLCBkZWNyeXB0KV0pXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvdXRcbn1cbmZ1bmN0aW9uIGVuY3J5cHRTdGFydCAoc2VsZiwgZGF0YSwgZGVjcnlwdCkge1xuICB2YXIgbGVuID0gZGF0YS5sZW5ndGhcbiAgdmFyIG91dCA9IHhvcihkYXRhLCBzZWxmLl9jYWNoZSlcbiAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jYWNoZS5zbGljZShsZW4pXG4gIHNlbGYuX3ByZXYgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9wcmV2LCBkZWNyeXB0ID8gZGF0YSA6IG91dF0pXG4gIHJldHVybiBvdXRcbn1cbiIsImZ1bmN0aW9uIGVuY3J5cHRCeXRlIChzZWxmLCBieXRlUGFyYW0sIGRlY3J5cHQpIHtcbiAgdmFyIHBhZFxuICB2YXIgaSA9IC0xXG4gIHZhciBsZW4gPSA4XG4gIHZhciBvdXQgPSAwXG4gIHZhciBiaXQsIHZhbHVlXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBwYWQgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gICAgYml0ID0gKGJ5dGVQYXJhbSAmICgxIDw8ICg3IC0gaSkpKSA/IDB4ODAgOiAwXG4gICAgdmFsdWUgPSBwYWRbMF0gXiBiaXRcbiAgICBvdXQgKz0gKCh2YWx1ZSAmIDB4ODApID4+IChpICUgOCkpXG4gICAgc2VsZi5fcHJldiA9IHNoaWZ0SW4oc2VsZi5fcHJldiwgZGVjcnlwdCA/IGJpdCA6IHZhbHVlKVxuICB9XG4gIHJldHVybiBvdXRcbn1cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBjaHVuaywgZGVjcnlwdCkge1xuICB2YXIgbGVuID0gY2h1bmsubGVuZ3RoXG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKGxlbilcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgb3V0W2ldID0gZW5jcnlwdEJ5dGUoc2VsZiwgY2h1bmtbaV0sIGRlY3J5cHQpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuZnVuY3Rpb24gc2hpZnRJbiAoYnVmZmVyLCB2YWx1ZSkge1xuICB2YXIgbGVuID0gYnVmZmVyLmxlbmd0aFxuICB2YXIgaSA9IC0xXG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKGJ1ZmZlci5sZW5ndGgpXG4gIGJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoW2J1ZmZlciwgbmV3IEJ1ZmZlcihbdmFsdWVdKV0pXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXRbaV0gPSBidWZmZXJbaV0gPDwgMSB8IGJ1ZmZlcltpICsgMV0gPj4gKDcpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwiZnVuY3Rpb24gZW5jcnlwdEJ5dGUgKHNlbGYsIGJ5dGVQYXJhbSwgZGVjcnlwdCkge1xuICB2YXIgcGFkID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhzZWxmLl9wcmV2KVxuICB2YXIgb3V0ID0gcGFkWzBdIF4gYnl0ZVBhcmFtXG4gIHNlbGYuX3ByZXYgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9wcmV2LnNsaWNlKDEpLCBuZXcgQnVmZmVyKFtkZWNyeXB0ID8gYnl0ZVBhcmFtIDogb3V0XSldKVxuICByZXR1cm4gb3V0XG59XG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgY2h1bmssIGRlY3J5cHQpIHtcbiAgdmFyIGxlbiA9IGNodW5rLmxlbmd0aFxuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihsZW4pXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dFtpXSA9IGVuY3J5cHRCeXRlKHNlbGYsIGNodW5rW2ldLCBkZWNyeXB0KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsInZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcblxuZnVuY3Rpb24gaW5jcjMyIChpdikge1xuICB2YXIgbGVuID0gaXYubGVuZ3RoXG4gIHZhciBpdGVtXG4gIHdoaWxlIChsZW4tLSkge1xuICAgIGl0ZW0gPSBpdi5yZWFkVUludDgobGVuKVxuICAgIGlmIChpdGVtID09PSAyNTUpIHtcbiAgICAgIGl2LndyaXRlVUludDgoMCwgbGVuKVxuICAgIH0gZWxzZSB7XG4gICAgICBpdGVtKytcbiAgICAgIGl2LndyaXRlVUludDgoaXRlbSwgbGVuKVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0QmxvY2sgKHNlbGYpIHtcbiAgdmFyIG91dCA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soc2VsZi5fcHJldilcbiAgaW5jcjMyKHNlbGYuX3ByZXYpXG4gIHJldHVybiBvdXRcbn1cblxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGNodW5rKSB7XG4gIHdoaWxlIChzZWxmLl9jYWNoZS5sZW5ndGggPCBjaHVuay5sZW5ndGgpIHtcbiAgICBzZWxmLl9jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3NlbGYuX2NhY2hlLCBnZXRCbG9jayhzZWxmKV0pXG4gIH1cbiAgdmFyIHBhZCA9IHNlbGYuX2NhY2hlLnNsaWNlKDAsIGNodW5rLmxlbmd0aClcbiAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jYWNoZS5zbGljZShjaHVuay5sZW5ndGgpXG4gIHJldHVybiB4b3IoY2h1bmssIHBhZClcbn1cbiIsInZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcblxuZnVuY3Rpb24gZ2V0QmxvY2sgKHNlbGYpIHtcbiAgc2VsZi5fcHJldiA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soc2VsZi5fcHJldilcbiAgcmV0dXJuIHNlbGYuX3ByZXZcbn1cblxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGNodW5rKSB7XG4gIHdoaWxlIChzZWxmLl9jYWNoZS5sZW5ndGggPCBjaHVuay5sZW5ndGgpIHtcbiAgICBzZWxmLl9jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3NlbGYuX2NhY2hlLCBnZXRCbG9jayhzZWxmKV0pXG4gIH1cblxuICB2YXIgcGFkID0gc2VsZi5fY2FjaGUuc2xpY2UoMCwgY2h1bmsubGVuZ3RoKVxuICBzZWxmLl9jYWNoZSA9IHNlbGYuX2NhY2hlLnNsaWNlKGNodW5rLmxlbmd0aClcbiAgcmV0dXJuIHhvcihjaHVuaywgcGFkKVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB4b3IgKGEsIGIpIHtcbiAgdmFyIGxlbmd0aCA9IE1hdGgubWluKGEubGVuZ3RoLCBiLmxlbmd0aClcbiAgdmFyIGJ1ZmZlciA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBidWZmZXJbaV0gPSBhW2ldIF4gYltpXVxuICB9XG5cbiAgcmV0dXJuIGJ1ZmZlclxufVxuIiwidmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ3N0cmVhbScpLlRyYW5zZm9ybVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2RlcicpLlN0cmluZ0RlY29kZXJcbm1vZHVsZS5leHBvcnRzID0gQ2lwaGVyQmFzZVxuaW5oZXJpdHMoQ2lwaGVyQmFzZSwgVHJhbnNmb3JtKVxuZnVuY3Rpb24gQ2lwaGVyQmFzZSAoaGFzaE1vZGUpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5oYXNoTW9kZSA9IHR5cGVvZiBoYXNoTW9kZSA9PT0gJ3N0cmluZydcbiAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICB0aGlzW2hhc2hNb2RlXSA9IHRoaXMuX2ZpbmFsT3JEaWdlc3RcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmZpbmFsID0gdGhpcy5fZmluYWxPckRpZ2VzdFxuICB9XG4gIHRoaXMuX2RlY29kZXIgPSBudWxsXG4gIHRoaXMuX2VuY29kaW5nID0gbnVsbFxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGlucHV0RW5jLCBvdXRwdXRFbmMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIGRhdGEgPSBuZXcgQnVmZmVyKGRhdGEsIGlucHV0RW5jKVxuICB9XG4gIHZhciBvdXREYXRhID0gdGhpcy5fdXBkYXRlKGRhdGEpXG4gIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuICBpZiAob3V0cHV0RW5jKSB7XG4gICAgb3V0RGF0YSA9IHRoaXMuX3RvU3RyaW5nKG91dERhdGEsIG91dHB1dEVuYylcbiAgfVxuICByZXR1cm4gb3V0RGF0YVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBdXRvUGFkZGluZyA9IGZ1bmN0aW9uICgpIHt9XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIHNldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEFBRCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gc2V0IGFhZCBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoZGF0YSwgXywgbmV4dCkge1xuICB2YXIgZXJyXG4gIHRyeSB7XG4gICAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZShkYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnB1c2godGhpcy5fdXBkYXRlKGRhdGEpKVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfSBmaW5hbGx5IHtcbiAgICBuZXh0KGVycilcbiAgfVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZsdXNoID0gZnVuY3Rpb24gKGRvbmUpIHtcbiAgdmFyIGVyclxuICB0cnkge1xuICAgIHRoaXMucHVzaCh0aGlzLl9maW5hbCgpKVxuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyID0gZVxuICB9IGZpbmFsbHkge1xuICAgIGRvbmUoZXJyKVxuICB9XG59XG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fZmluYWxPckRpZ2VzdCA9IGZ1bmN0aW9uIChvdXRwdXRFbmMpIHtcbiAgdmFyIG91dERhdGEgPSB0aGlzLl9maW5hbCgpIHx8IG5ldyBCdWZmZXIoJycpXG4gIGlmIChvdXRwdXRFbmMpIHtcbiAgICBvdXREYXRhID0gdGhpcy5fdG9TdHJpbmcob3V0RGF0YSwgb3V0cHV0RW5jLCB0cnVlKVxuICB9XG4gIHJldHVybiBvdXREYXRhXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90b1N0cmluZyA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jLCBmaW5hbCkge1xuICBpZiAoIXRoaXMuX2RlY29kZXIpIHtcbiAgICB0aGlzLl9kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKVxuICAgIHRoaXMuX2VuY29kaW5nID0gZW5jXG4gIH1cbiAgaWYgKHRoaXMuX2VuY29kaW5nICE9PSBlbmMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NhblxcJ3Qgc3dpdGNoIGVuY29kaW5ncycpXG4gIH1cbiAgdmFyIG91dCA9IHRoaXMuX2RlY29kZXIud3JpdGUodmFsdWUpXG4gIGlmIChmaW5hbCkge1xuICAgIG91dCArPSB0aGlzLl9kZWNvZGVyLmVuZCgpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG5cbmluaGVyaXRzKFN0cmVhbUNpcGhlciwgVHJhbnNmb3JtKVxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW1DaXBoZXJcbmZ1bmN0aW9uIFN0cmVhbUNpcGhlciAobW9kZSwga2V5LCBpdiwgZGVjcnlwdCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3RyZWFtQ2lwaGVyKSkge1xuICAgIHJldHVybiBuZXcgU3RyZWFtQ2lwaGVyKG1vZGUsIGtleSwgaXYpXG4gIH1cbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5fY2lwaGVyID0gbmV3IGFlcy5BRVMoa2V5KVxuICB0aGlzLl9wcmV2ID0gbmV3IEJ1ZmZlcihpdi5sZW5ndGgpXG4gIHRoaXMuX2NhY2hlID0gbmV3IEJ1ZmZlcignJylcbiAgdGhpcy5fc2VjQ2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxuICB0aGlzLl9kZWNyeXB0ID0gZGVjcnlwdFxuICBpdi5jb3B5KHRoaXMuX3ByZXYpXG4gIHRoaXMuX21vZGUgPSBtb2RlXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgcmV0dXJuIHRoaXMuX21vZGUuZW5jcnlwdCh0aGlzLCBjaHVuaywgdGhpcy5fZGVjcnlwdClcbn1cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9jaXBoZXIuc2NydWIoKVxufVxuIiwidmFyIG1kNSA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoL21kNScpXG5tb2R1bGUuZXhwb3J0cyA9IEVWUF9CeXRlc1RvS2V5XG5mdW5jdGlvbiBFVlBfQnl0ZXNUb0tleSAocGFzc3dvcmQsIHNhbHQsIGtleUxlbiwgaXZMZW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIocGFzc3dvcmQpKSB7XG4gICAgcGFzc3dvcmQgPSBuZXcgQnVmZmVyKHBhc3N3b3JkLCAnYmluYXJ5JylcbiAgfVxuICBpZiAoc2FsdCAmJiAhQnVmZmVyLmlzQnVmZmVyKHNhbHQpKSB7XG4gICAgc2FsdCA9IG5ldyBCdWZmZXIoc2FsdCwgJ2JpbmFyeScpXG4gIH1cbiAga2V5TGVuID0ga2V5TGVuIC8gOFxuICBpdkxlbiA9IGl2TGVuIHx8IDBcbiAgdmFyIGtpID0gMFxuICB2YXIgaWkgPSAwXG4gIHZhciBrZXkgPSBuZXcgQnVmZmVyKGtleUxlbilcbiAgdmFyIGl2ID0gbmV3IEJ1ZmZlcihpdkxlbilcbiAgdmFyIGFkZG1kID0gMFxuICB2YXIgbWRfYnVmXG4gIHZhciBpXG4gIHZhciBidWZzID0gW11cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAoYWRkbWQrKyA+IDApIHtcbiAgICAgIGJ1ZnMucHVzaChtZF9idWYpXG4gICAgfVxuICAgIGJ1ZnMucHVzaChwYXNzd29yZClcbiAgICBpZiAoc2FsdCkge1xuICAgICAgYnVmcy5wdXNoKHNhbHQpXG4gICAgfVxuICAgIG1kX2J1ZiA9IG1kNShCdWZmZXIuY29uY2F0KGJ1ZnMpKVxuICAgIGJ1ZnMgPSBbXVxuICAgIGkgPSAwXG4gICAgaWYgKGtleUxlbiA+IDApIHtcbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGlmIChrZXlMZW4gPT09IDApIHtcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICAgIGlmIChpID09PSBtZF9idWYubGVuZ3RoKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBrZXlba2krK10gPSBtZF9idWZbaV1cbiAgICAgICAga2V5TGVuLS1cbiAgICAgICAgaSsrXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpdkxlbiA+IDAgJiYgaSAhPT0gbWRfYnVmLmxlbmd0aCkge1xuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgaWYgKGl2TGVuID09PSAwKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaSA9PT0gbWRfYnVmLmxlbmd0aCkge1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgaXZbaWkrK10gPSBtZF9idWZbaV1cbiAgICAgICAgaXZMZW4tLVxuICAgICAgICBpKytcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGtleUxlbiA9PT0gMCAmJiBpdkxlbiA9PT0gMCkge1xuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbiAgZm9yIChpID0gMDsgaSA8IG1kX2J1Zi5sZW5ndGg7IGkrKykge1xuICAgIG1kX2J1ZltpXSA9IDBcbiAgfVxuICByZXR1cm4ge1xuICAgIGtleToga2V5LFxuICAgIGl2OiBpdlxuICB9XG59XG4iLCIvLyBtdWNoIG9mIHRoaXMgYmFzZWQgb24gaHR0cHM6Ly9naXRodWIuY29tL2luZHV0bnkvc2VsZi1zaWduZWQvYmxvYi9naC1wYWdlcy9saWIvcnNhLmpzXG52YXIgY3JlYXRlSG1hYyA9IHJlcXVpcmUoJ2NyZWF0ZS1obWFjJylcbnZhciBjcnQgPSByZXF1aXJlKCdicm93c2VyaWZ5LXJzYScpXG52YXIgY3VydmVzID0gcmVxdWlyZSgnLi9jdXJ2ZXMnKVxudmFyIGVsbGlwdGljID0gcmVxdWlyZSgnZWxsaXB0aWMnKVxudmFyIHBhcnNlS2V5cyA9IHJlcXVpcmUoJ3BhcnNlLWFzbjEnKVxuXG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpXG52YXIgRUMgPSBlbGxpcHRpYy5lY1xuXG5mdW5jdGlvbiBzaWduIChoYXNoLCBrZXksIGhhc2hUeXBlLCBzaWduVHlwZSkge1xuICB2YXIgcHJpdiA9IHBhcnNlS2V5cyhrZXkpXG4gIGlmIChwcml2LmN1cnZlKSB7XG4gICAgaWYgKHNpZ25UeXBlICE9PSAnZWNkc2EnKSB0aHJvdyBuZXcgRXJyb3IoJ3dyb25nIHByaXZhdGUga2V5IHR5cGUnKVxuXG4gICAgcmV0dXJuIGVjU2lnbihoYXNoLCBwcml2KVxuICB9IGVsc2UgaWYgKHByaXYudHlwZSA9PT0gJ2RzYScpIHtcbiAgICBpZiAoc2lnblR5cGUgIT09ICdkc2EnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3dyb25nIHByaXZhdGUga2V5IHR5cGUnKVxuICAgIH1cbiAgICByZXR1cm4gZHNhU2lnbihoYXNoLCBwcml2LCBoYXNoVHlwZSlcbiAgfSBlbHNlIHtcbiAgICBpZiAoc2lnblR5cGUgIT09ICdyc2EnKSB0aHJvdyBuZXcgRXJyb3IoJ3dyb25nIHByaXZhdGUga2V5IHR5cGUnKVxuICB9XG5cbiAgdmFyIGxlbiA9IHByaXYubW9kdWx1cy5ieXRlTGVuZ3RoKClcbiAgdmFyIHBhZCA9IFsgMCwgMSBdXG4gIHdoaWxlIChoYXNoLmxlbmd0aCArIHBhZC5sZW5ndGggKyAxIDwgbGVuKSB7XG4gICAgcGFkLnB1c2goMHhmZilcbiAgfVxuICBwYWQucHVzaCgweDAwKVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBoYXNoLmxlbmd0aCkge1xuICAgIHBhZC5wdXNoKGhhc2hbaV0pXG4gIH1cblxuICB2YXIgb3V0ID0gY3J0KHBhZCwgcHJpdilcbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiBlY1NpZ24gKGhhc2gsIHByaXYpIHtcbiAgdmFyIGN1cnZlSWQgPSBjdXJ2ZXNbcHJpdi5jdXJ2ZS5qb2luKCcuJyldXG4gIGlmICghY3VydmVJZCkgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGN1cnZlICcgKyBwcml2LmN1cnZlLmpvaW4oJy4nKSlcblxuICB2YXIgY3VydmUgPSBuZXcgRUMoY3VydmVJZClcbiAgdmFyIGtleSA9IGN1cnZlLmdlbktleVBhaXIoKVxuXG4gIGtleS5faW1wb3J0UHJpdmF0ZShwcml2LnByaXZhdGVLZXkpXG4gIHZhciBvdXQgPSBrZXkuc2lnbihoYXNoKVxuXG4gIHJldHVybiBuZXcgQnVmZmVyKG91dC50b0RFUigpKVxufVxuXG5mdW5jdGlvbiBkc2FTaWduIChoYXNoLCBwcml2LCBhbGdvKSB7XG4gIHZhciB4ID0gcHJpdi5wYXJhbXMucHJpdl9rZXlcbiAgdmFyIHAgPSBwcml2LnBhcmFtcy5wXG4gIHZhciBxID0gcHJpdi5wYXJhbXMucVxuICB2YXIgZyA9IHByaXYucGFyYW1zLmdcbiAgdmFyIHIgPSBuZXcgQk4oMClcbiAgdmFyIGtcbiAgdmFyIEggPSBiaXRzMmludChoYXNoLCBxKS5tb2QocSlcbiAgdmFyIHMgPSBmYWxzZVxuICB2YXIga3YgPSBnZXRLZXkoeCwgcSwgaGFzaCwgYWxnbylcbiAgd2hpbGUgKHMgPT09IGZhbHNlKSB7XG4gICAgayA9IG1ha2VLZXkocSwga3YsIGFsZ28pXG4gICAgciA9IG1ha2VSKGcsIGssIHAsIHEpXG4gICAgcyA9IGsuaW52bShxKS5pbXVsKEguYWRkKHgubXVsKHIpKSkubW9kKHEpXG4gICAgaWYgKCFzLmNtcG4oMCkpIHtcbiAgICAgIHMgPSBmYWxzZVxuICAgICAgciA9IG5ldyBCTigwKVxuICAgIH1cbiAgfVxuICByZXR1cm4gdG9ERVIociwgcylcbn1cblxuZnVuY3Rpb24gdG9ERVIgKHIsIHMpIHtcbiAgciA9IHIudG9BcnJheSgpXG4gIHMgPSBzLnRvQXJyYXkoKVxuXG4gIC8vIFBhZCB2YWx1ZXNcbiAgaWYgKHJbMF0gJiAweDgwKSB7XG4gICAgciA9IFsgMCBdLmNvbmNhdChyKVxuICB9XG4gIC8vIFBhZCB2YWx1ZXNcbiAgaWYgKHNbMF0gJiAweDgwKSB7XG4gICAgcyA9IFswXS5jb25jYXQocylcbiAgfVxuXG4gIHZhciB0b3RhbCA9IHIubGVuZ3RoICsgcy5sZW5ndGggKyA0XG4gIHZhciByZXMgPSBbIDB4MzAsIHRvdGFsLCAweDAyLCByLmxlbmd0aCBdXG4gIHJlcyA9IHJlcy5jb25jYXQociwgWyAweDAyLCBzLmxlbmd0aCBdLCBzKVxuICByZXR1cm4gbmV3IEJ1ZmZlcihyZXMpXG59XG5cbmZ1bmN0aW9uIGdldEtleSAoeCwgcSwgaGFzaCwgYWxnbykge1xuICB4ID0gbmV3IEJ1ZmZlcih4LnRvQXJyYXkoKSlcbiAgaWYgKHgubGVuZ3RoIDwgcS5ieXRlTGVuZ3RoKCkpIHtcbiAgICB2YXIgemVyb3MgPSBuZXcgQnVmZmVyKHEuYnl0ZUxlbmd0aCgpIC0geC5sZW5ndGgpXG4gICAgemVyb3MuZmlsbCgwKVxuICAgIHggPSBCdWZmZXIuY29uY2F0KFt6ZXJvcywgeF0pXG4gIH1cbiAgdmFyIGhsZW4gPSBoYXNoLmxlbmd0aFxuICB2YXIgaGJpdHMgPSBiaXRzMm9jdGV0cyhoYXNoLCBxKVxuICB2YXIgdiA9IG5ldyBCdWZmZXIoaGxlbilcbiAgdi5maWxsKDEpXG4gIHZhciBrID0gbmV3IEJ1ZmZlcihobGVuKVxuICBrLmZpbGwoMClcbiAgayA9IGNyZWF0ZUhtYWMoYWxnbywgaylcbiAgICAudXBkYXRlKHYpXG4gICAgLnVwZGF0ZShuZXcgQnVmZmVyKFswXSkpXG4gICAgLnVwZGF0ZSh4KVxuICAgIC51cGRhdGUoaGJpdHMpXG4gICAgLmRpZ2VzdCgpXG4gIHYgPSBjcmVhdGVIbWFjKGFsZ28sIGspXG4gICAgLnVwZGF0ZSh2KVxuICAgIC5kaWdlc3QoKVxuICBrID0gY3JlYXRlSG1hYyhhbGdvLCBrKVxuICAgIC51cGRhdGUodilcbiAgICAudXBkYXRlKG5ldyBCdWZmZXIoWzFdKSlcbiAgICAudXBkYXRlKHgpXG4gICAgLnVwZGF0ZShoYml0cylcbiAgICAuZGlnZXN0KClcbiAgdiA9IGNyZWF0ZUhtYWMoYWxnbywgaylcbiAgICAudXBkYXRlKHYpXG4gICAgLmRpZ2VzdCgpXG4gIHJldHVybiB7XG4gICAgazogayxcbiAgICB2OiB2XG4gIH1cbn1cblxuZnVuY3Rpb24gYml0czJpbnQgKG9iaXRzLCBxKSB7XG4gIHZhciBiaXRzID0gbmV3IEJOKG9iaXRzKVxuICB2YXIgc2hpZnQgPSAob2JpdHMubGVuZ3RoIDw8IDMpIC0gcS5iaXRMZW5ndGgoKVxuICBpZiAoc2hpZnQgPiAwKSB7XG4gICAgYml0cy5pc2hybihzaGlmdClcbiAgfVxuICByZXR1cm4gYml0c1xufVxuXG5mdW5jdGlvbiBiaXRzMm9jdGV0cyAoYml0cywgcSkge1xuICBiaXRzID0gYml0czJpbnQoYml0cywgcSlcbiAgYml0cyA9IGJpdHMubW9kKHEpXG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKGJpdHMudG9BcnJheSgpKVxuICBpZiAob3V0Lmxlbmd0aCA8IHEuYnl0ZUxlbmd0aCgpKSB7XG4gICAgdmFyIHplcm9zID0gbmV3IEJ1ZmZlcihxLmJ5dGVMZW5ndGgoKSAtIG91dC5sZW5ndGgpXG4gICAgemVyb3MuZmlsbCgwKVxuICAgIG91dCA9IEJ1ZmZlci5jb25jYXQoW3plcm9zLCBvdXRdKVxuICB9XG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gbWFrZUtleSAocSwga3YsIGFsZ28pIHtcbiAgdmFyIHQsIGtcblxuICBkbyB7XG4gICAgdCA9IG5ldyBCdWZmZXIoJycpXG5cbiAgICB3aGlsZSAodC5sZW5ndGggKiA4IDwgcS5iaXRMZW5ndGgoKSkge1xuICAgICAga3YudiA9IGNyZWF0ZUhtYWMoYWxnbywga3YuaylcbiAgICAgICAgLnVwZGF0ZShrdi52KVxuICAgICAgICAuZGlnZXN0KClcbiAgICAgIHQgPSBCdWZmZXIuY29uY2F0KFt0LCBrdi52XSlcbiAgICB9XG5cbiAgICBrID0gYml0czJpbnQodCwgcSlcbiAgICBrdi5rID0gY3JlYXRlSG1hYyhhbGdvLCBrdi5rKVxuICAgICAgLnVwZGF0ZShrdi52KVxuICAgICAgLnVwZGF0ZShuZXcgQnVmZmVyKFswXSkpXG4gICAgICAuZGlnZXN0KClcbiAgICBrdi52ID0gY3JlYXRlSG1hYyhhbGdvLCBrdi5rKVxuICAgICAgLnVwZGF0ZShrdi52KVxuICAgICAgLmRpZ2VzdCgpXG4gIH0gd2hpbGUgKGsuY21wKHEpICE9PSAtMSlcblxuICByZXR1cm4ga1xufVxuXG5mdW5jdGlvbiBtYWtlUiAoZywgaywgcCwgcSkge1xuICByZXR1cm4gZy50b1JlZChCTi5tb250KHApKS5yZWRQb3coaykuZnJvbVJlZCgpLm1vZChxKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNpZ25cbm1vZHVsZS5leHBvcnRzLmdldEtleSA9IGdldEtleVxubW9kdWxlLmV4cG9ydHMubWFrZUtleSA9IG1ha2VLZXlcbiIsIi8vIG11Y2ggb2YgdGhpcyBiYXNlZCBvbiBodHRwczovL2dpdGh1Yi5jb20vaW5kdXRueS9zZWxmLXNpZ25lZC9ibG9iL2doLXBhZ2VzL2xpYi9yc2EuanNcbnZhciBjdXJ2ZXMgPSByZXF1aXJlKCcuL2N1cnZlcycpXG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCdlbGxpcHRpYycpXG52YXIgcGFyc2VLZXlzID0gcmVxdWlyZSgncGFyc2UtYXNuMScpXG5cbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJylcbnZhciBFQyA9IGVsbGlwdGljLmVjXG5cbmZ1bmN0aW9uIHZlcmlmeSAoc2lnLCBoYXNoLCBrZXksIHNpZ25UeXBlKSB7XG4gIHZhciBwdWIgPSBwYXJzZUtleXMoa2V5KVxuICBpZiAocHViLnR5cGUgPT09ICdlYycpIHtcbiAgICBpZiAoc2lnblR5cGUgIT09ICdlY2RzYScpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignd3JvbmcgcHVibGljIGtleSB0eXBlJylcbiAgICB9XG4gICAgcmV0dXJuIGVjVmVyaWZ5KHNpZywgaGFzaCwgcHViKVxuICB9IGVsc2UgaWYgKHB1Yi50eXBlID09PSAnZHNhJykge1xuICAgIGlmIChzaWduVHlwZSAhPT0gJ2RzYScpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignd3JvbmcgcHVibGljIGtleSB0eXBlJylcbiAgICB9XG4gICAgcmV0dXJuIGRzYVZlcmlmeShzaWcsIGhhc2gsIHB1YilcbiAgfSBlbHNlIHtcbiAgICBpZiAoc2lnblR5cGUgIT09ICdyc2EnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3dyb25nIHB1YmxpYyBrZXkgdHlwZScpXG4gICAgfVxuICB9XG4gIHZhciBsZW4gPSBwdWIubW9kdWx1cy5ieXRlTGVuZ3RoKClcbiAgdmFyIHBhZCA9IFsgMSBdXG4gIHZhciBwYWROdW0gPSAwXG4gIHdoaWxlIChoYXNoLmxlbmd0aCArIHBhZC5sZW5ndGggKyAyIDwgbGVuKSB7XG4gICAgcGFkLnB1c2goMHhmZilcbiAgICBwYWROdW0rK1xuICB9XG4gIHBhZC5wdXNoKDB4MDApXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGhhc2gubGVuZ3RoKSB7XG4gICAgcGFkLnB1c2goaGFzaFtpXSlcbiAgfVxuICBwYWQgPSBuZXcgQnVmZmVyKHBhZClcbiAgdmFyIHJlZCA9IEJOLm1vbnQocHViLm1vZHVsdXMpXG4gIHNpZyA9IG5ldyBCTihzaWcpLnRvUmVkKHJlZClcblxuICBzaWcgPSBzaWcucmVkUG93KG5ldyBCTihwdWIucHVibGljRXhwb25lbnQpKVxuXG4gIHNpZyA9IG5ldyBCdWZmZXIoc2lnLmZyb21SZWQoKS50b0FycmF5KCkpXG4gIHZhciBvdXQgPSAwXG4gIGlmIChwYWROdW0gPCA4KSB7XG4gICAgb3V0ID0gMVxuICB9XG4gIGxlbiA9IE1hdGgubWluKHNpZy5sZW5ndGgsIHBhZC5sZW5ndGgpXG4gIGlmIChzaWcubGVuZ3RoICE9PSBwYWQubGVuZ3RoKSB7XG4gICAgb3V0ID0gMVxuICB9XG5cbiAgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXQgfD0gKHNpZ1tpXSBeIHBhZFtpXSlcbiAgfVxuICByZXR1cm4gb3V0ID09PSAwXG59XG5cbmZ1bmN0aW9uIGVjVmVyaWZ5IChzaWcsIGhhc2gsIHB1Yikge1xuICB2YXIgY3VydmVJZCA9IGN1cnZlc1twdWIuZGF0YS5hbGdvcml0aG0uY3VydmUuam9pbignLicpXVxuICBpZiAoIWN1cnZlSWQpIHRocm93IG5ldyBFcnJvcigndW5rbm93biBjdXJ2ZSAnICsgcHViLmRhdGEuYWxnb3JpdGhtLmN1cnZlLmpvaW4oJy4nKSlcblxuICB2YXIgY3VydmUgPSBuZXcgRUMoY3VydmVJZClcbiAgdmFyIHB1YmtleSA9IHB1Yi5kYXRhLnN1YmplY3RQcml2YXRlS2V5LmRhdGFcblxuICByZXR1cm4gY3VydmUudmVyaWZ5KGhhc2gsIHNpZywgcHVia2V5KVxufVxuXG5mdW5jdGlvbiBkc2FWZXJpZnkgKHNpZywgaGFzaCwgcHViKSB7XG4gIHZhciBwID0gcHViLmRhdGEucFxuICB2YXIgcSA9IHB1Yi5kYXRhLnFcbiAgdmFyIGcgPSBwdWIuZGF0YS5nXG4gIHZhciB5ID0gcHViLmRhdGEucHViX2tleVxuICB2YXIgdW5wYWNrZWQgPSBwYXJzZUtleXMuc2lnbmF0dXJlLmRlY29kZShzaWcsICdkZXInKVxuICB2YXIgcyA9IHVucGFja2VkLnNcbiAgdmFyIHIgPSB1bnBhY2tlZC5yXG4gIGNoZWNrVmFsdWUocywgcSlcbiAgY2hlY2tWYWx1ZShyLCBxKVxuICB2YXIgbW9udHAgPSBCTi5tb250KHApXG4gIHZhciB3ID0gcy5pbnZtKHEpXG4gIHZhciB2ID0gZy50b1JlZChtb250cClcbiAgICAucmVkUG93KG5ldyBCTihoYXNoKS5tdWwodykubW9kKHEpKVxuICAgIC5mcm9tUmVkKClcbiAgICAubXVsKFxuICAgICAgeS50b1JlZChtb250cClcbiAgICAgICAgLnJlZFBvdyhyLm11bCh3KS5tb2QocSkpXG4gICAgICAgIC5mcm9tUmVkKClcbiAgKS5tb2QocCkubW9kKHEpXG4gIHJldHVybiAhdi5jbXAocilcbn1cblxuZnVuY3Rpb24gY2hlY2tWYWx1ZSAoYiwgcSkge1xuICBpZiAoYi5jbXBuKDApIDw9IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgc2lnJylcbiAgfVxuICBpZiAoYi5jbXAocSkgPj0gcSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBzaWcnKVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdmVyaWZ5XG4iLCJ2YXIgZWxsaXB0aWMgPSByZXF1aXJlKCdlbGxpcHRpYycpO1xudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBjcmVhdGVFQ0RIKGN1cnZlKSB7XG5cdHJldHVybiBuZXcgRUNESChjdXJ2ZSk7XG59O1xuXG52YXIgYWxpYXNlcyA9IHtcblx0c2VjcDI1NmsxOiB7XG5cdFx0bmFtZTogJ3NlY3AyNTZrMScsXG5cdFx0Ynl0ZUxlbmd0aDogMzJcblx0fSxcblx0c2VjcDIyNHIxOiB7XG5cdFx0bmFtZTogJ3AyMjQnLFxuXHRcdGJ5dGVMZW5ndGg6IDI4XG5cdH0sXG5cdHByaW1lMjU2djE6IHtcblx0XHRuYW1lOiAncDI1NicsXG5cdFx0Ynl0ZUxlbmd0aDogMzJcblx0fSxcblx0cHJpbWUxOTJ2MToge1xuXHRcdG5hbWU6ICdwMTkyJyxcblx0XHRieXRlTGVuZ3RoOiAyNFxuXHR9LFxuXHRlZDI1NTE5OiB7XG5cdFx0bmFtZTogJ2VkMjU1MTknLFxuXHRcdGJ5dGVMZW5ndGg6IDMyXG5cdH0sXG5cdHNlY3AzODRyMToge1xuXHRcdG5hbWU6ICdwMzg0Jyxcblx0XHRieXRlTGVuZ3RoOiA0OFxuXHR9LFxuXHRzZWNwNTIxcjE6IHtcblx0XHRuYW1lOiAncDUyMScsXG5cdFx0Ynl0ZUxlbmd0aDogNjZcblx0fVxufTtcblxuYWxpYXNlcy5wMjI0ID0gYWxpYXNlcy5zZWNwMjI0cjE7XG5hbGlhc2VzLnAyNTYgPSBhbGlhc2VzLnNlY3AyNTZyMSA9IGFsaWFzZXMucHJpbWUyNTZ2MTtcbmFsaWFzZXMucDE5MiA9IGFsaWFzZXMuc2VjcDE5MnIxID0gYWxpYXNlcy5wcmltZTE5MnYxO1xuYWxpYXNlcy5wMzg0ID0gYWxpYXNlcy5zZWNwMzg0cjE7XG5hbGlhc2VzLnA1MjEgPSBhbGlhc2VzLnNlY3A1MjFyMTtcblxuZnVuY3Rpb24gRUNESChjdXJ2ZSkge1xuXHR0aGlzLmN1cnZlVHlwZSA9IGFsaWFzZXNbY3VydmVdO1xuXHRpZiAoIXRoaXMuY3VydmVUeXBlICkge1xuXHRcdHRoaXMuY3VydmVUeXBlID0ge1xuXHRcdFx0bmFtZTogY3VydmVcblx0XHR9O1xuXHR9XG5cdHRoaXMuY3VydmUgPSBuZXcgZWxsaXB0aWMuZWModGhpcy5jdXJ2ZVR5cGUubmFtZSk7XG5cdHRoaXMua2V5cyA9IHZvaWQgMDtcbn1cblxuRUNESC5wcm90b3R5cGUuZ2VuZXJhdGVLZXlzID0gZnVuY3Rpb24gKGVuYywgZm9ybWF0KSB7XG5cdHRoaXMua2V5cyA9IHRoaXMuY3VydmUuZ2VuS2V5UGFpcigpO1xuXHRyZXR1cm4gdGhpcy5nZXRQdWJsaWNLZXkoZW5jLCBmb3JtYXQpO1xufTtcblxuRUNESC5wcm90b3R5cGUuY29tcHV0ZVNlY3JldCA9IGZ1bmN0aW9uIChvdGhlciwgaW5lbmMsIGVuYykge1xuXHRpbmVuYyA9IGluZW5jIHx8ICd1dGY4Jztcblx0aWYgKCFCdWZmZXIuaXNCdWZmZXIob3RoZXIpKSB7XG5cdFx0b3RoZXIgPSBuZXcgQnVmZmVyKG90aGVyLCBpbmVuYyk7XG5cdH1cblx0dmFyIG90aGVyUHViID0gdGhpcy5jdXJ2ZS5rZXlGcm9tUHVibGljKG90aGVyKS5nZXRQdWJsaWMoKTtcblx0dmFyIG91dCA9IG90aGVyUHViLm11bCh0aGlzLmtleXMuZ2V0UHJpdmF0ZSgpKS5nZXRYKCk7XG5cdHJldHVybiBmb3JtYXRSZXR1cm5WYWx1ZShvdXQsIGVuYywgdGhpcy5jdXJ2ZVR5cGUuYnl0ZUxlbmd0aCk7XG59O1xuXG5FQ0RILnByb3RvdHlwZS5nZXRQdWJsaWNLZXkgPSBmdW5jdGlvbiAoZW5jLCBmb3JtYXQpIHtcblx0dmFyIGtleSA9IHRoaXMua2V5cy5nZXRQdWJsaWMoZm9ybWF0ID09PSAnY29tcHJlc3NlZCcsIHRydWUpO1xuXHRpZiAoZm9ybWF0ID09PSAnaHlicmlkJykge1xuXHRcdGlmIChrZXlba2V5Lmxlbmd0aCAtIDFdICUgMikge1xuXHRcdFx0a2V5WzBdID0gNztcblx0XHR9IGVsc2Uge1xuXHRcdFx0a2V5IFswXSA9IDY7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBmb3JtYXRSZXR1cm5WYWx1ZShrZXksIGVuYyk7XG59O1xuXG5FQ0RILnByb3RvdHlwZS5nZXRQcml2YXRlS2V5ID0gZnVuY3Rpb24gKGVuYykge1xuXHRyZXR1cm4gZm9ybWF0UmV0dXJuVmFsdWUodGhpcy5rZXlzLmdldFByaXZhdGUoKSwgZW5jKTtcbn07XG5cbkVDREgucHJvdG90eXBlLnNldFB1YmxpY0tleSA9IGZ1bmN0aW9uIChwdWIsIGVuYykge1xuXHRlbmMgPSBlbmMgfHwgJ3V0ZjgnO1xuXHRpZiAoIUJ1ZmZlci5pc0J1ZmZlcihwdWIpKSB7XG5cdFx0cHViID0gbmV3IEJ1ZmZlcihwdWIsIGVuYyk7XG5cdH1cblx0dGhpcy5rZXlzLl9pbXBvcnRQdWJsaWMocHViKTtcblx0cmV0dXJuIHRoaXM7XG59O1xuXG5FQ0RILnByb3RvdHlwZS5zZXRQcml2YXRlS2V5ID0gZnVuY3Rpb24gKHByaXYsIGVuYykge1xuXHRlbmMgPSBlbmMgfHwgJ3V0ZjgnO1xuXHRpZiAoIUJ1ZmZlci5pc0J1ZmZlcihwcml2KSkge1xuXHRcdHByaXYgPSBuZXcgQnVmZmVyKHByaXYsIGVuYyk7XG5cdH1cblx0dmFyIF9wcml2ID0gbmV3IEJOKHByaXYpO1xuXHRfcHJpdiA9IF9wcml2LnRvU3RyaW5nKDE2KTtcblx0dGhpcy5rZXlzLl9pbXBvcnRQcml2YXRlKF9wcml2KTtcblx0cmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBmb3JtYXRSZXR1cm5WYWx1ZShibiwgZW5jLCBsZW4pIHtcblx0aWYgKCFBcnJheS5pc0FycmF5KGJuKSkge1xuXHRcdGJuID0gYm4udG9BcnJheSgpO1xuXHR9XG5cdHZhciBidWYgPSBuZXcgQnVmZmVyKGJuKTtcblx0aWYgKGxlbiAmJiBidWYubGVuZ3RoIDwgbGVuKSB7XG5cdFx0dmFyIHplcm9zID0gbmV3IEJ1ZmZlcihsZW4gLSBidWYubGVuZ3RoKTtcblx0XHR6ZXJvcy5maWxsKDApO1xuXHRcdGJ1ZiA9IEJ1ZmZlci5jb25jYXQoW3plcm9zLCBidWZdKTtcblx0fVxuXHRpZiAoIWVuYykge1xuXHRcdHJldHVybiBidWY7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIGJ1Zi50b1N0cmluZyhlbmMpO1xuXHR9XG59XG4iLCIndXNlIHN0cmljdCc7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgbWQ1ID0gcmVxdWlyZSgnLi9tZDUnKVxudmFyIHJtZDE2MCA9IHJlcXVpcmUoJ3JpcGVtZDE2MCcpXG52YXIgc2hhID0gcmVxdWlyZSgnc2hhLmpzJylcblxudmFyIEJhc2UgPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG5cbmZ1bmN0aW9uIEhhc2hOb0NvbnN0cnVjdG9yKGhhc2gpIHtcbiAgQmFzZS5jYWxsKHRoaXMsICdkaWdlc3QnKVxuXG4gIHRoaXMuX2hhc2ggPSBoYXNoXG4gIHRoaXMuYnVmZmVycyA9IFtdXG59XG5cbmluaGVyaXRzKEhhc2hOb0NvbnN0cnVjdG9yLCBCYXNlKVxuXG5IYXNoTm9Db25zdHJ1Y3Rvci5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuYnVmZmVycy5wdXNoKGRhdGEpXG59XG5cbkhhc2hOb0NvbnN0cnVjdG9yLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBidWYgPSBCdWZmZXIuY29uY2F0KHRoaXMuYnVmZmVycylcbiAgdmFyIHIgPSB0aGlzLl9oYXNoKGJ1ZilcbiAgdGhpcy5idWZmZXJzID0gbnVsbFxuXG4gIHJldHVybiByXG59XG5cbmZ1bmN0aW9uIEhhc2goaGFzaCkge1xuICBCYXNlLmNhbGwodGhpcywgJ2RpZ2VzdCcpXG5cbiAgdGhpcy5faGFzaCA9IGhhc2hcbn1cblxuaW5oZXJpdHMoSGFzaCwgQmFzZSlcblxuSGFzaC5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuX2hhc2gudXBkYXRlKGRhdGEpXG59XG5cbkhhc2gucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuX2hhc2guZGlnZXN0KClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBjcmVhdGVIYXNoIChhbGcpIHtcbiAgYWxnID0gYWxnLnRvTG93ZXJDYXNlKClcbiAgaWYgKCdtZDUnID09PSBhbGcpIHJldHVybiBuZXcgSGFzaE5vQ29uc3RydWN0b3IobWQ1KVxuICBpZiAoJ3JtZDE2MCcgPT09IGFsZyB8fCAncmlwZW1kMTYwJyA9PT0gYWxnKSByZXR1cm4gbmV3IEhhc2hOb0NvbnN0cnVjdG9yKHJtZDE2MClcblxuICByZXR1cm4gbmV3IEhhc2goc2hhKGFsZykpXG59XG4iLCIndXNlIHN0cmljdCc7XG52YXIgaW50U2l6ZSA9IDQ7XG52YXIgemVyb0J1ZmZlciA9IG5ldyBCdWZmZXIoaW50U2l6ZSk7IHplcm9CdWZmZXIuZmlsbCgwKTtcbnZhciBjaHJzeiA9IDg7XG5cbmZ1bmN0aW9uIHRvQXJyYXkoYnVmLCBiaWdFbmRpYW4pIHtcbiAgaWYgKChidWYubGVuZ3RoICUgaW50U2l6ZSkgIT09IDApIHtcbiAgICB2YXIgbGVuID0gYnVmLmxlbmd0aCArIChpbnRTaXplIC0gKGJ1Zi5sZW5ndGggJSBpbnRTaXplKSk7XG4gICAgYnVmID0gQnVmZmVyLmNvbmNhdChbYnVmLCB6ZXJvQnVmZmVyXSwgbGVuKTtcbiAgfVxuXG4gIHZhciBhcnIgPSBbXTtcbiAgdmFyIGZuID0gYmlnRW5kaWFuID8gYnVmLnJlYWRJbnQzMkJFIDogYnVmLnJlYWRJbnQzMkxFO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ1Zi5sZW5ndGg7IGkgKz0gaW50U2l6ZSkge1xuICAgIGFyci5wdXNoKGZuLmNhbGwoYnVmLCBpKSk7XG4gIH1cbiAgcmV0dXJuIGFycjtcbn1cblxuZnVuY3Rpb24gdG9CdWZmZXIoYXJyLCBzaXplLCBiaWdFbmRpYW4pIHtcbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoc2l6ZSk7XG4gIHZhciBmbiA9IGJpZ0VuZGlhbiA/IGJ1Zi53cml0ZUludDMyQkUgOiBidWYud3JpdGVJbnQzMkxFO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIGZuLmNhbGwoYnVmLCBhcnJbaV0sIGkgKiA0LCB0cnVlKTtcbiAgfVxuICByZXR1cm4gYnVmO1xufVxuXG5mdW5jdGlvbiBoYXNoKGJ1ZiwgZm4sIGhhc2hTaXplLCBiaWdFbmRpYW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkgYnVmID0gbmV3IEJ1ZmZlcihidWYpO1xuICB2YXIgYXJyID0gZm4odG9BcnJheShidWYsIGJpZ0VuZGlhbiksIGJ1Zi5sZW5ndGggKiBjaHJzeik7XG4gIHJldHVybiB0b0J1ZmZlcihhcnIsIGhhc2hTaXplLCBiaWdFbmRpYW4pO1xufVxuZXhwb3J0cy5oYXNoID0gaGFzaDsiLCIndXNlIHN0cmljdCc7XG4vKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBSU0EgRGF0YSBTZWN1cml0eSwgSW5jLiBNRDUgTWVzc2FnZVxuICogRGlnZXN0IEFsZ29yaXRobSwgYXMgZGVmaW5lZCBpbiBSRkMgMTMyMS5cbiAqIFZlcnNpb24gMi4xIENvcHlyaWdodCAoQykgUGF1bCBKb2huc3RvbiAxOTk5IC0gMjAwMi5cbiAqIE90aGVyIGNvbnRyaWJ1dG9yczogR3JlZyBIb2x0LCBBbmRyZXcgS2VwZXJ0LCBZZG5hciwgTG9zdGluZXRcbiAqIERpc3RyaWJ1dGVkIHVuZGVyIHRoZSBCU0QgTGljZW5zZVxuICogU2VlIGh0dHA6Ly9wYWpob21lLm9yZy51ay9jcnlwdC9tZDUgZm9yIG1vcmUgaW5mby5cbiAqL1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xuXG4vKlxuICogQ2FsY3VsYXRlIHRoZSBNRDUgb2YgYW4gYXJyYXkgb2YgbGl0dGxlLWVuZGlhbiB3b3JkcywgYW5kIGEgYml0IGxlbmd0aFxuICovXG5mdW5jdGlvbiBjb3JlX21kNSh4LCBsZW4pXG57XG4gIC8qIGFwcGVuZCBwYWRkaW5nICovXG4gIHhbbGVuID4+IDVdIHw9IDB4ODAgPDwgKChsZW4pICUgMzIpO1xuICB4WygoKGxlbiArIDY0KSA+Pj4gOSkgPDwgNCkgKyAxNF0gPSBsZW47XG5cbiAgdmFyIGEgPSAgMTczMjU4NDE5MztcbiAgdmFyIGIgPSAtMjcxNzMzODc5O1xuICB2YXIgYyA9IC0xNzMyNTg0MTk0O1xuICB2YXIgZCA9ICAyNzE3MzM4Nzg7XG5cbiAgZm9yKHZhciBpID0gMDsgaSA8IHgubGVuZ3RoOyBpICs9IDE2KVxuICB7XG4gICAgdmFyIG9sZGEgPSBhO1xuICAgIHZhciBvbGRiID0gYjtcbiAgICB2YXIgb2xkYyA9IGM7XG4gICAgdmFyIG9sZGQgPSBkO1xuXG4gICAgYSA9IG1kNV9mZihhLCBiLCBjLCBkLCB4W2krIDBdLCA3ICwgLTY4MDg3NjkzNik7XG4gICAgZCA9IG1kNV9mZihkLCBhLCBiLCBjLCB4W2krIDFdLCAxMiwgLTM4OTU2NDU4Nik7XG4gICAgYyA9IG1kNV9mZihjLCBkLCBhLCBiLCB4W2krIDJdLCAxNywgIDYwNjEwNTgxOSk7XG4gICAgYiA9IG1kNV9mZihiLCBjLCBkLCBhLCB4W2krIDNdLCAyMiwgLTEwNDQ1MjUzMzApO1xuICAgIGEgPSBtZDVfZmYoYSwgYiwgYywgZCwgeFtpKyA0XSwgNyAsIC0xNzY0MTg4OTcpO1xuICAgIGQgPSBtZDVfZmYoZCwgYSwgYiwgYywgeFtpKyA1XSwgMTIsICAxMjAwMDgwNDI2KTtcbiAgICBjID0gbWQ1X2ZmKGMsIGQsIGEsIGIsIHhbaSsgNl0sIDE3LCAtMTQ3MzIzMTM0MSk7XG4gICAgYiA9IG1kNV9mZihiLCBjLCBkLCBhLCB4W2krIDddLCAyMiwgLTQ1NzA1OTgzKTtcbiAgICBhID0gbWQ1X2ZmKGEsIGIsIGMsIGQsIHhbaSsgOF0sIDcgLCAgMTc3MDAzNTQxNik7XG4gICAgZCA9IG1kNV9mZihkLCBhLCBiLCBjLCB4W2krIDldLCAxMiwgLTE5NTg0MTQ0MTcpO1xuICAgIGMgPSBtZDVfZmYoYywgZCwgYSwgYiwgeFtpKzEwXSwgMTcsIC00MjA2Myk7XG4gICAgYiA9IG1kNV9mZihiLCBjLCBkLCBhLCB4W2krMTFdLCAyMiwgLTE5OTA0MDQxNjIpO1xuICAgIGEgPSBtZDVfZmYoYSwgYiwgYywgZCwgeFtpKzEyXSwgNyAsICAxODA0NjAzNjgyKTtcbiAgICBkID0gbWQ1X2ZmKGQsIGEsIGIsIGMsIHhbaSsxM10sIDEyLCAtNDAzNDExMDEpO1xuICAgIGMgPSBtZDVfZmYoYywgZCwgYSwgYiwgeFtpKzE0XSwgMTcsIC0xNTAyMDAyMjkwKTtcbiAgICBiID0gbWQ1X2ZmKGIsIGMsIGQsIGEsIHhbaSsxNV0sIDIyLCAgMTIzNjUzNTMyOSk7XG5cbiAgICBhID0gbWQ1X2dnKGEsIGIsIGMsIGQsIHhbaSsgMV0sIDUgLCAtMTY1Nzk2NTEwKTtcbiAgICBkID0gbWQ1X2dnKGQsIGEsIGIsIGMsIHhbaSsgNl0sIDkgLCAtMTA2OTUwMTYzMik7XG4gICAgYyA9IG1kNV9nZyhjLCBkLCBhLCBiLCB4W2krMTFdLCAxNCwgIDY0MzcxNzcxMyk7XG4gICAgYiA9IG1kNV9nZyhiLCBjLCBkLCBhLCB4W2krIDBdLCAyMCwgLTM3Mzg5NzMwMik7XG4gICAgYSA9IG1kNV9nZyhhLCBiLCBjLCBkLCB4W2krIDVdLCA1ICwgLTcwMTU1ODY5MSk7XG4gICAgZCA9IG1kNV9nZyhkLCBhLCBiLCBjLCB4W2krMTBdLCA5ICwgIDM4MDE2MDgzKTtcbiAgICBjID0gbWQ1X2dnKGMsIGQsIGEsIGIsIHhbaSsxNV0sIDE0LCAtNjYwNDc4MzM1KTtcbiAgICBiID0gbWQ1X2dnKGIsIGMsIGQsIGEsIHhbaSsgNF0sIDIwLCAtNDA1NTM3ODQ4KTtcbiAgICBhID0gbWQ1X2dnKGEsIGIsIGMsIGQsIHhbaSsgOV0sIDUgLCAgNTY4NDQ2NDM4KTtcbiAgICBkID0gbWQ1X2dnKGQsIGEsIGIsIGMsIHhbaSsxNF0sIDkgLCAtMTAxOTgwMzY5MCk7XG4gICAgYyA9IG1kNV9nZyhjLCBkLCBhLCBiLCB4W2krIDNdLCAxNCwgLTE4NzM2Mzk2MSk7XG4gICAgYiA9IG1kNV9nZyhiLCBjLCBkLCBhLCB4W2krIDhdLCAyMCwgIDExNjM1MzE1MDEpO1xuICAgIGEgPSBtZDVfZ2coYSwgYiwgYywgZCwgeFtpKzEzXSwgNSAsIC0xNDQ0NjgxNDY3KTtcbiAgICBkID0gbWQ1X2dnKGQsIGEsIGIsIGMsIHhbaSsgMl0sIDkgLCAtNTE0MDM3ODQpO1xuICAgIGMgPSBtZDVfZ2coYywgZCwgYSwgYiwgeFtpKyA3XSwgMTQsICAxNzM1MzI4NDczKTtcbiAgICBiID0gbWQ1X2dnKGIsIGMsIGQsIGEsIHhbaSsxMl0sIDIwLCAtMTkyNjYwNzczNCk7XG5cbiAgICBhID0gbWQ1X2hoKGEsIGIsIGMsIGQsIHhbaSsgNV0sIDQgLCAtMzc4NTU4KTtcbiAgICBkID0gbWQ1X2hoKGQsIGEsIGIsIGMsIHhbaSsgOF0sIDExLCAtMjAyMjU3NDQ2Myk7XG4gICAgYyA9IG1kNV9oaChjLCBkLCBhLCBiLCB4W2krMTFdLCAxNiwgIDE4MzkwMzA1NjIpO1xuICAgIGIgPSBtZDVfaGgoYiwgYywgZCwgYSwgeFtpKzE0XSwgMjMsIC0zNTMwOTU1Nik7XG4gICAgYSA9IG1kNV9oaChhLCBiLCBjLCBkLCB4W2krIDFdLCA0ICwgLTE1MzA5OTIwNjApO1xuICAgIGQgPSBtZDVfaGgoZCwgYSwgYiwgYywgeFtpKyA0XSwgMTEsICAxMjcyODkzMzUzKTtcbiAgICBjID0gbWQ1X2hoKGMsIGQsIGEsIGIsIHhbaSsgN10sIDE2LCAtMTU1NDk3NjMyKTtcbiAgICBiID0gbWQ1X2hoKGIsIGMsIGQsIGEsIHhbaSsxMF0sIDIzLCAtMTA5NDczMDY0MCk7XG4gICAgYSA9IG1kNV9oaChhLCBiLCBjLCBkLCB4W2krMTNdLCA0ICwgIDY4MTI3OTE3NCk7XG4gICAgZCA9IG1kNV9oaChkLCBhLCBiLCBjLCB4W2krIDBdLCAxMSwgLTM1ODUzNzIyMik7XG4gICAgYyA9IG1kNV9oaChjLCBkLCBhLCBiLCB4W2krIDNdLCAxNiwgLTcyMjUyMTk3OSk7XG4gICAgYiA9IG1kNV9oaChiLCBjLCBkLCBhLCB4W2krIDZdLCAyMywgIDc2MDI5MTg5KTtcbiAgICBhID0gbWQ1X2hoKGEsIGIsIGMsIGQsIHhbaSsgOV0sIDQgLCAtNjQwMzY0NDg3KTtcbiAgICBkID0gbWQ1X2hoKGQsIGEsIGIsIGMsIHhbaSsxMl0sIDExLCAtNDIxODE1ODM1KTtcbiAgICBjID0gbWQ1X2hoKGMsIGQsIGEsIGIsIHhbaSsxNV0sIDE2LCAgNTMwNzQyNTIwKTtcbiAgICBiID0gbWQ1X2hoKGIsIGMsIGQsIGEsIHhbaSsgMl0sIDIzLCAtOTk1MzM4NjUxKTtcblxuICAgIGEgPSBtZDVfaWkoYSwgYiwgYywgZCwgeFtpKyAwXSwgNiAsIC0xOTg2MzA4NDQpO1xuICAgIGQgPSBtZDVfaWkoZCwgYSwgYiwgYywgeFtpKyA3XSwgMTAsICAxMTI2ODkxNDE1KTtcbiAgICBjID0gbWQ1X2lpKGMsIGQsIGEsIGIsIHhbaSsxNF0sIDE1LCAtMTQxNjM1NDkwNSk7XG4gICAgYiA9IG1kNV9paShiLCBjLCBkLCBhLCB4W2krIDVdLCAyMSwgLTU3NDM0MDU1KTtcbiAgICBhID0gbWQ1X2lpKGEsIGIsIGMsIGQsIHhbaSsxMl0sIDYgLCAgMTcwMDQ4NTU3MSk7XG4gICAgZCA9IG1kNV9paShkLCBhLCBiLCBjLCB4W2krIDNdLCAxMCwgLTE4OTQ5ODY2MDYpO1xuICAgIGMgPSBtZDVfaWkoYywgZCwgYSwgYiwgeFtpKzEwXSwgMTUsIC0xMDUxNTIzKTtcbiAgICBiID0gbWQ1X2lpKGIsIGMsIGQsIGEsIHhbaSsgMV0sIDIxLCAtMjA1NDkyMjc5OSk7XG4gICAgYSA9IG1kNV9paShhLCBiLCBjLCBkLCB4W2krIDhdLCA2ICwgIDE4NzMzMTMzNTkpO1xuICAgIGQgPSBtZDVfaWkoZCwgYSwgYiwgYywgeFtpKzE1XSwgMTAsIC0zMDYxMTc0NCk7XG4gICAgYyA9IG1kNV9paShjLCBkLCBhLCBiLCB4W2krIDZdLCAxNSwgLTE1NjAxOTgzODApO1xuICAgIGIgPSBtZDVfaWkoYiwgYywgZCwgYSwgeFtpKzEzXSwgMjEsICAxMzA5MTUxNjQ5KTtcbiAgICBhID0gbWQ1X2lpKGEsIGIsIGMsIGQsIHhbaSsgNF0sIDYgLCAtMTQ1NTIzMDcwKTtcbiAgICBkID0gbWQ1X2lpKGQsIGEsIGIsIGMsIHhbaSsxMV0sIDEwLCAtMTEyMDIxMDM3OSk7XG4gICAgYyA9IG1kNV9paShjLCBkLCBhLCBiLCB4W2krIDJdLCAxNSwgIDcxODc4NzI1OSk7XG4gICAgYiA9IG1kNV9paShiLCBjLCBkLCBhLCB4W2krIDldLCAyMSwgLTM0MzQ4NTU1MSk7XG5cbiAgICBhID0gc2FmZV9hZGQoYSwgb2xkYSk7XG4gICAgYiA9IHNhZmVfYWRkKGIsIG9sZGIpO1xuICAgIGMgPSBzYWZlX2FkZChjLCBvbGRjKTtcbiAgICBkID0gc2FmZV9hZGQoZCwgb2xkZCk7XG4gIH1cbiAgcmV0dXJuIEFycmF5KGEsIGIsIGMsIGQpO1xuXG59XG5cbi8qXG4gKiBUaGVzZSBmdW5jdGlvbnMgaW1wbGVtZW50IHRoZSBmb3VyIGJhc2ljIG9wZXJhdGlvbnMgdGhlIGFsZ29yaXRobSB1c2VzLlxuICovXG5mdW5jdGlvbiBtZDVfY21uKHEsIGEsIGIsIHgsIHMsIHQpXG57XG4gIHJldHVybiBzYWZlX2FkZChiaXRfcm9sKHNhZmVfYWRkKHNhZmVfYWRkKGEsIHEpLCBzYWZlX2FkZCh4LCB0KSksIHMpLGIpO1xufVxuZnVuY3Rpb24gbWQ1X2ZmKGEsIGIsIGMsIGQsIHgsIHMsIHQpXG57XG4gIHJldHVybiBtZDVfY21uKChiICYgYykgfCAoKH5iKSAmIGQpLCBhLCBiLCB4LCBzLCB0KTtcbn1cbmZ1bmN0aW9uIG1kNV9nZyhhLCBiLCBjLCBkLCB4LCBzLCB0KVxue1xuICByZXR1cm4gbWQ1X2NtbigoYiAmIGQpIHwgKGMgJiAofmQpKSwgYSwgYiwgeCwgcywgdCk7XG59XG5mdW5jdGlvbiBtZDVfaGgoYSwgYiwgYywgZCwgeCwgcywgdClcbntcbiAgcmV0dXJuIG1kNV9jbW4oYiBeIGMgXiBkLCBhLCBiLCB4LCBzLCB0KTtcbn1cbmZ1bmN0aW9uIG1kNV9paShhLCBiLCBjLCBkLCB4LCBzLCB0KVxue1xuICByZXR1cm4gbWQ1X2NtbihjIF4gKGIgfCAofmQpKSwgYSwgYiwgeCwgcywgdCk7XG59XG5cbi8qXG4gKiBBZGQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeMzIuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9ucyBpbnRlcm5hbGx5XG4gKiB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICovXG5mdW5jdGlvbiBzYWZlX2FkZCh4LCB5KVxue1xuICB2YXIgbHN3ID0gKHggJiAweEZGRkYpICsgKHkgJiAweEZGRkYpO1xuICB2YXIgbXN3ID0gKHggPj4gMTYpICsgKHkgPj4gMTYpICsgKGxzdyA+PiAxNik7XG4gIHJldHVybiAobXN3IDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xufVxuXG4vKlxuICogQml0d2lzZSByb3RhdGUgYSAzMi1iaXQgbnVtYmVyIHRvIHRoZSBsZWZ0LlxuICovXG5mdW5jdGlvbiBiaXRfcm9sKG51bSwgY250KVxue1xuICByZXR1cm4gKG51bSA8PCBjbnQpIHwgKG51bSA+Pj4gKDMyIC0gY250KSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gbWQ1KGJ1Zikge1xuICByZXR1cm4gaGVscGVycy5oYXNoKGJ1ZiwgY29yZV9tZDUsIDE2KTtcbn07IiwidmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ3N0cmVhbScpLlRyYW5zZm9ybVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2RlcicpLlN0cmluZ0RlY29kZXJcbm1vZHVsZS5leHBvcnRzID0gQ2lwaGVyQmFzZVxuaW5oZXJpdHMoQ2lwaGVyQmFzZSwgVHJhbnNmb3JtKVxuZnVuY3Rpb24gQ2lwaGVyQmFzZSAoaGFzaE1vZGUpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5oYXNoTW9kZSA9IHR5cGVvZiBoYXNoTW9kZSA9PT0gJ3N0cmluZydcbiAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICB0aGlzW2hhc2hNb2RlXSA9IHRoaXMuX2ZpbmFsT3JEaWdlc3RcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmZpbmFsID0gdGhpcy5fZmluYWxPckRpZ2VzdFxuICB9XG4gIHRoaXMuX2RlY29kZXIgPSBudWxsXG4gIHRoaXMuX2VuY29kaW5nID0gbnVsbFxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGlucHV0RW5jLCBvdXRwdXRFbmMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIGRhdGEgPSBuZXcgQnVmZmVyKGRhdGEsIGlucHV0RW5jKVxuICB9XG4gIHZhciBvdXREYXRhID0gdGhpcy5fdXBkYXRlKGRhdGEpXG4gIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuICBpZiAob3V0cHV0RW5jKSB7XG4gICAgb3V0RGF0YSA9IHRoaXMuX3RvU3RyaW5nKG91dERhdGEsIG91dHB1dEVuYylcbiAgfVxuICByZXR1cm4gb3V0RGF0YVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBdXRvUGFkZGluZyA9IGZ1bmN0aW9uICgpIHt9XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIHNldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEFBRCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gc2V0IGFhZCBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoZGF0YSwgXywgbmV4dCkge1xuICB2YXIgZXJyXG4gIHRyeSB7XG4gICAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZShkYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnB1c2godGhpcy5fdXBkYXRlKGRhdGEpKVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfSBmaW5hbGx5IHtcbiAgICBuZXh0KGVycilcbiAgfVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZsdXNoID0gZnVuY3Rpb24gKGRvbmUpIHtcbiAgdmFyIGVyclxuICB0cnkge1xuICAgIHRoaXMucHVzaCh0aGlzLl9maW5hbCgpKVxuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyID0gZVxuICB9IGZpbmFsbHkge1xuICAgIGRvbmUoZXJyKVxuICB9XG59XG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fZmluYWxPckRpZ2VzdCA9IGZ1bmN0aW9uIChvdXRwdXRFbmMpIHtcbiAgdmFyIG91dERhdGEgPSB0aGlzLl9maW5hbCgpIHx8IG5ldyBCdWZmZXIoJycpXG4gIGlmIChvdXRwdXRFbmMpIHtcbiAgICBvdXREYXRhID0gdGhpcy5fdG9TdHJpbmcob3V0RGF0YSwgb3V0cHV0RW5jLCB0cnVlKVxuICB9XG4gIHJldHVybiBvdXREYXRhXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90b1N0cmluZyA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jLCBmaW5hbCkge1xuICBpZiAoIXRoaXMuX2RlY29kZXIpIHtcbiAgICB0aGlzLl9kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKVxuICAgIHRoaXMuX2VuY29kaW5nID0gZW5jXG4gIH1cbiAgaWYgKHRoaXMuX2VuY29kaW5nICE9PSBlbmMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NhblxcJ3Qgc3dpdGNoIGVuY29kaW5ncycpXG4gIH1cbiAgdmFyIG91dCA9IHRoaXMuX2RlY29kZXIud3JpdGUodmFsdWUpXG4gIGlmIChmaW5hbCkge1xuICAgIG91dCArPSB0aGlzLl9kZWNvZGVyLmVuZCgpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwiLypcbkNyeXB0b0pTIHYzLjEuMlxuY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzXG4oYykgMjAwOS0yMDEzIGJ5IEplZmYgTW90dC4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbmNvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qcy93aWtpL0xpY2Vuc2VcbiovXG4vKiogQHByZXNlcnZlXG4oYykgMjAxMiBieSBDw6lkcmljIE1lc25pbC4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cblxuUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuXG4gICAgLSBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gICAgLSBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG5cblRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbi8vIGNvbnN0YW50cyB0YWJsZVxudmFyIHpsID0gW1xuICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LFxuICA3LCA0LCAxMywgMSwgMTAsIDYsIDE1LCAzLCAxMiwgMCwgOSwgNSwgMiwgMTQsIDExLCA4LFxuICAzLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyLFxuICAxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyLFxuICA0LCAwLCA1LCA5LCA3LCAxMiwgMiwgMTAsIDE0LCAxLCAzLCA4LCAxMSwgNiwgMTUsIDEzXG5dXG5cbnZhciB6ciA9IFtcbiAgNSwgMTQsIDcsIDAsIDksIDIsIDExLCA0LCAxMywgNiwgMTUsIDgsIDEsIDEwLCAzLCAxMixcbiAgNiwgMTEsIDMsIDcsIDAsIDEzLCA1LCAxMCwgMTQsIDE1LCA4LCAxMiwgNCwgOSwgMSwgMixcbiAgMTUsIDUsIDEsIDMsIDcsIDE0LCA2LCA5LCAxMSwgOCwgMTIsIDIsIDEwLCAwLCA0LCAxMyxcbiAgOCwgNiwgNCwgMSwgMywgMTEsIDE1LCAwLCA1LCAxMiwgMiwgMTMsIDksIDcsIDEwLCAxNCxcbiAgMTIsIDE1LCAxMCwgNCwgMSwgNSwgOCwgNywgNiwgMiwgMTMsIDE0LCAwLCAzLCA5LCAxMVxuXVxuXG52YXIgc2wgPSBbXG4gIDExLCAxNCwgMTUsIDEyLCA1LCA4LCA3LCA5LCAxMSwgMTMsIDE0LCAxNSwgNiwgNywgOSwgOCxcbiAgNywgNiwgOCwgMTMsIDExLCA5LCA3LCAxNSwgNywgMTIsIDE1LCA5LCAxMSwgNywgMTMsIDEyLFxuICAxMSwgMTMsIDYsIDcsIDE0LCA5LCAxMywgMTUsIDE0LCA4LCAxMywgNiwgNSwgMTIsIDcsIDUsXG4gIDExLCAxMiwgMTQsIDE1LCAxNCwgMTUsIDksIDgsIDksIDE0LCA1LCA2LCA4LCA2LCA1LCAxMixcbiAgOSwgMTUsIDUsIDExLCA2LCA4LCAxMywgMTIsIDUsIDEyLCAxMywgMTQsIDExLCA4LCA1LCA2XG5dXG5cbnZhciBzciA9IFtcbiAgOCwgOSwgOSwgMTEsIDEzLCAxNSwgMTUsIDUsIDcsIDcsIDgsIDExLCAxNCwgMTQsIDEyLCA2LFxuICA5LCAxMywgMTUsIDcsIDEyLCA4LCA5LCAxMSwgNywgNywgMTIsIDcsIDYsIDE1LCAxMywgMTEsXG4gIDksIDcsIDE1LCAxMSwgOCwgNiwgNiwgMTQsIDEyLCAxMywgNSwgMTQsIDEzLCAxMywgNywgNSxcbiAgMTUsIDUsIDgsIDExLCAxNCwgMTQsIDYsIDE0LCA2LCA5LCAxMiwgOSwgMTIsIDUsIDE1LCA4LFxuICA4LCA1LCAxMiwgOSwgMTIsIDUsIDE0LCA2LCA4LCAxMywgNiwgNSwgMTUsIDEzLCAxMSwgMTFcbl1cblxudmFyIGhsID0gWzB4MDAwMDAwMDAsIDB4NUE4Mjc5OTksIDB4NkVEOUVCQTEsIDB4OEYxQkJDREMsIDB4QTk1M0ZENEVdXG52YXIgaHIgPSBbMHg1MEEyOEJFNiwgMHg1QzRERDEyNCwgMHg2RDcwM0VGMywgMHg3QTZENzZFOSwgMHgwMDAwMDAwMF1cblxuZnVuY3Rpb24gYnl0ZXNUb1dvcmRzIChieXRlcykge1xuICB2YXIgd29yZHMgPSBbXVxuICBmb3IgKHZhciBpID0gMCwgYiA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKywgYiArPSA4KSB7XG4gICAgd29yZHNbYiA+Pj4gNV0gfD0gYnl0ZXNbaV0gPDwgKDI0IC0gYiAlIDMyKVxuICB9XG4gIHJldHVybiB3b3Jkc1xufVxuXG5mdW5jdGlvbiB3b3Jkc1RvQnl0ZXMgKHdvcmRzKSB7XG4gIHZhciBieXRlcyA9IFtdXG4gIGZvciAodmFyIGIgPSAwOyBiIDwgd29yZHMubGVuZ3RoICogMzI7IGIgKz0gOCkge1xuICAgIGJ5dGVzLnB1c2goKHdvcmRzW2IgPj4+IDVdID4+PiAoMjQgLSBiICUgMzIpKSAmIDB4RkYpXG4gIH1cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NCbG9jayAoSCwgTSwgb2Zmc2V0KSB7XG4gIC8vIHN3YXAgZW5kaWFuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgIHZhciBvZmZzZXRfaSA9IG9mZnNldCArIGlcbiAgICB2YXIgTV9vZmZzZXRfaSA9IE1bb2Zmc2V0X2ldXG5cbiAgICAvLyBTd2FwXG4gICAgTVtvZmZzZXRfaV0gPSAoXG4gICAgICAoKChNX29mZnNldF9pIDw8IDgpIHwgKE1fb2Zmc2V0X2kgPj4+IDI0KSkgJiAweDAwZmYwMGZmKSB8XG4gICAgICAoKChNX29mZnNldF9pIDw8IDI0KSB8IChNX29mZnNldF9pID4+PiA4KSkgJiAweGZmMDBmZjAwKVxuICAgIClcbiAgfVxuXG4gIC8vIFdvcmtpbmcgdmFyaWFibGVzXG4gIHZhciBhbCwgYmwsIGNsLCBkbCwgZWxcbiAgdmFyIGFyLCBiciwgY3IsIGRyLCBlclxuXG4gIGFyID0gYWwgPSBIWzBdXG4gIGJyID0gYmwgPSBIWzFdXG4gIGNyID0gY2wgPSBIWzJdXG4gIGRyID0gZGwgPSBIWzNdXG4gIGVyID0gZWwgPSBIWzRdXG5cbiAgLy8gY29tcHV0YXRpb25cbiAgdmFyIHRcbiAgZm9yIChpID0gMDsgaSA8IDgwOyBpICs9IDEpIHtcbiAgICB0ID0gKGFsICsgTVtvZmZzZXQgKyB6bFtpXV0pIHwgMFxuICAgIGlmIChpIDwgMTYpIHtcbiAgICAgIHQgKz0gZjEoYmwsIGNsLCBkbCkgKyBobFswXVxuICAgIH0gZWxzZSBpZiAoaSA8IDMyKSB7XG4gICAgICB0ICs9IGYyKGJsLCBjbCwgZGwpICsgaGxbMV1cbiAgICB9IGVsc2UgaWYgKGkgPCA0OCkge1xuICAgICAgdCArPSBmMyhibCwgY2wsIGRsKSArIGhsWzJdXG4gICAgfSBlbHNlIGlmIChpIDwgNjQpIHtcbiAgICAgIHQgKz0gZjQoYmwsIGNsLCBkbCkgKyBobFszXVxuICAgIH0gZWxzZSB7Ly8gaWYgKGk8ODApIHtcbiAgICAgIHQgKz0gZjUoYmwsIGNsLCBkbCkgKyBobFs0XVxuICAgIH1cbiAgICB0ID0gdCB8IDBcbiAgICB0ID0gcm90bCh0LCBzbFtpXSlcbiAgICB0ID0gKHQgKyBlbCkgfCAwXG4gICAgYWwgPSBlbFxuICAgIGVsID0gZGxcbiAgICBkbCA9IHJvdGwoY2wsIDEwKVxuICAgIGNsID0gYmxcbiAgICBibCA9IHRcblxuICAgIHQgPSAoYXIgKyBNW29mZnNldCArIHpyW2ldXSkgfCAwXG4gICAgaWYgKGkgPCAxNikge1xuICAgICAgdCArPSBmNShiciwgY3IsIGRyKSArIGhyWzBdXG4gICAgfSBlbHNlIGlmIChpIDwgMzIpIHtcbiAgICAgIHQgKz0gZjQoYnIsIGNyLCBkcikgKyBoclsxXVxuICAgIH0gZWxzZSBpZiAoaSA8IDQ4KSB7XG4gICAgICB0ICs9IGYzKGJyLCBjciwgZHIpICsgaHJbMl1cbiAgICB9IGVsc2UgaWYgKGkgPCA2NCkge1xuICAgICAgdCArPSBmMihiciwgY3IsIGRyKSArIGhyWzNdXG4gICAgfSBlbHNlIHsvLyBpZiAoaTw4MCkge1xuICAgICAgdCArPSBmMShiciwgY3IsIGRyKSArIGhyWzRdXG4gICAgfVxuXG4gICAgdCA9IHQgfCAwXG4gICAgdCA9IHJvdGwodCwgc3JbaV0pXG4gICAgdCA9ICh0ICsgZXIpIHwgMFxuICAgIGFyID0gZXJcbiAgICBlciA9IGRyXG4gICAgZHIgPSByb3RsKGNyLCAxMClcbiAgICBjciA9IGJyXG4gICAgYnIgPSB0XG4gIH1cblxuICAvLyBpbnRlcm1lZGlhdGUgaGFzaCB2YWx1ZVxuICB0ID0gKEhbMV0gKyBjbCArIGRyKSB8IDBcbiAgSFsxXSA9IChIWzJdICsgZGwgKyBlcikgfCAwXG4gIEhbMl0gPSAoSFszXSArIGVsICsgYXIpIHwgMFxuICBIWzNdID0gKEhbNF0gKyBhbCArIGJyKSB8IDBcbiAgSFs0XSA9IChIWzBdICsgYmwgKyBjcikgfCAwXG4gIEhbMF0gPSB0XG59XG5cbmZ1bmN0aW9uIGYxICh4LCB5LCB6KSB7XG4gIHJldHVybiAoKHgpIF4gKHkpIF4gKHopKVxufVxuXG5mdW5jdGlvbiBmMiAoeCwgeSwgeikge1xuICByZXR1cm4gKCgoeCkgJiAoeSkpIHwgKCh+eCkgJiAoeikpKVxufVxuXG5mdW5jdGlvbiBmMyAoeCwgeSwgeikge1xuICByZXR1cm4gKCgoeCkgfCAofih5KSkpIF4gKHopKVxufVxuXG5mdW5jdGlvbiBmNCAoeCwgeSwgeikge1xuICByZXR1cm4gKCgoeCkgJiAoeikpIHwgKCh5KSAmICh+KHopKSkpXG59XG5cbmZ1bmN0aW9uIGY1ICh4LCB5LCB6KSB7XG4gIHJldHVybiAoKHgpIF4gKCh5KSB8ICh+KHopKSkpXG59XG5cbmZ1bmN0aW9uIHJvdGwgKHgsIG4pIHtcbiAgcmV0dXJuICh4IDw8IG4pIHwgKHggPj4+ICgzMiAtIG4pKVxufVxuXG5mdW5jdGlvbiByaXBlbWQxNjAgKG1lc3NhZ2UpIHtcbiAgdmFyIEggPSBbMHg2NzQ1MjMwMSwgMHhFRkNEQUI4OSwgMHg5OEJBRENGRSwgMHgxMDMyNTQ3NiwgMHhDM0QyRTFGMF1cblxuICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgbWVzc2FnZSA9IG5ldyBCdWZmZXIobWVzc2FnZSwgJ3V0ZjgnKVxuICB9XG5cbiAgdmFyIG0gPSBieXRlc1RvV29yZHMobWVzc2FnZSlcblxuICB2YXIgbkJpdHNMZWZ0ID0gbWVzc2FnZS5sZW5ndGggKiA4XG4gIHZhciBuQml0c1RvdGFsID0gbWVzc2FnZS5sZW5ndGggKiA4XG5cbiAgLy8gQWRkIHBhZGRpbmdcbiAgbVtuQml0c0xlZnQgPj4+IDVdIHw9IDB4ODAgPDwgKDI0IC0gbkJpdHNMZWZ0ICUgMzIpXG4gIG1bKCgobkJpdHNMZWZ0ICsgNjQpID4+PiA5KSA8PCA0KSArIDE0XSA9IChcbiAgICAoKChuQml0c1RvdGFsIDw8IDgpIHwgKG5CaXRzVG90YWwgPj4+IDI0KSkgJiAweDAwZmYwMGZmKSB8XG4gICAgKCgobkJpdHNUb3RhbCA8PCAyNCkgfCAobkJpdHNUb3RhbCA+Pj4gOCkpICYgMHhmZjAwZmYwMClcbiAgKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbS5sZW5ndGg7IGkgKz0gMTYpIHtcbiAgICBwcm9jZXNzQmxvY2soSCwgbSwgaSlcbiAgfVxuXG4gIC8vIHN3YXAgZW5kaWFuXG4gIGZvciAoaSA9IDA7IGkgPCA1OyBpKyspIHtcbiAgICAvLyBzaG9ydGN1dFxuICAgIHZhciBIX2kgPSBIW2ldXG5cbiAgICAvLyBTd2FwXG4gICAgSFtpXSA9ICgoKEhfaSA8PCA4KSB8IChIX2kgPj4+IDI0KSkgJiAweDAwZmYwMGZmKSB8XG4gICAgICAoKChIX2kgPDwgMjQpIHwgKEhfaSA+Pj4gOCkpICYgMHhmZjAwZmYwMClcbiAgfVxuXG4gIHZhciBkaWdlc3RieXRlcyA9IHdvcmRzVG9CeXRlcyhIKVxuICByZXR1cm4gbmV3IEJ1ZmZlcihkaWdlc3RieXRlcylcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByaXBlbWQxNjBcbiIsIi8vIHByb3RvdHlwZSBjbGFzcyBmb3IgaGFzaCBmdW5jdGlvbnNcbmZ1bmN0aW9uIEhhc2ggKGJsb2NrU2l6ZSwgZmluYWxTaXplKSB7XG4gIHRoaXMuX2Jsb2NrID0gbmV3IEJ1ZmZlcihibG9ja1NpemUpXG4gIHRoaXMuX2ZpbmFsU2l6ZSA9IGZpbmFsU2l6ZVxuICB0aGlzLl9ibG9ja1NpemUgPSBibG9ja1NpemVcbiAgdGhpcy5fbGVuID0gMFxuICB0aGlzLl9zID0gMFxufVxuXG5IYXNoLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSwgZW5jKSB7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmMgPSBlbmMgfHwgJ3V0ZjgnXG4gICAgZGF0YSA9IG5ldyBCdWZmZXIoZGF0YSwgZW5jKVxuICB9XG5cbiAgdmFyIGwgPSB0aGlzLl9sZW4gKz0gZGF0YS5sZW5ndGhcbiAgdmFyIHMgPSB0aGlzLl9zIHx8IDBcbiAgdmFyIGYgPSAwXG4gIHZhciBidWZmZXIgPSB0aGlzLl9ibG9ja1xuXG4gIHdoaWxlIChzIDwgbCkge1xuICAgIHZhciB0ID0gTWF0aC5taW4oZGF0YS5sZW5ndGgsIGYgKyB0aGlzLl9ibG9ja1NpemUgLSAocyAlIHRoaXMuX2Jsb2NrU2l6ZSkpXG4gICAgdmFyIGNoID0gKHQgLSBmKVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaDsgaSsrKSB7XG4gICAgICBidWZmZXJbKHMgJSB0aGlzLl9ibG9ja1NpemUpICsgaV0gPSBkYXRhW2kgKyBmXVxuICAgIH1cblxuICAgIHMgKz0gY2hcbiAgICBmICs9IGNoXG5cbiAgICBpZiAoKHMgJSB0aGlzLl9ibG9ja1NpemUpID09PSAwKSB7XG4gICAgICB0aGlzLl91cGRhdGUoYnVmZmVyKVxuICAgIH1cbiAgfVxuICB0aGlzLl9zID0gc1xuXG4gIHJldHVybiB0aGlzXG59XG5cbkhhc2gucHJvdG90eXBlLmRpZ2VzdCA9IGZ1bmN0aW9uIChlbmMpIHtcbiAgLy8gU3VwcG9zZSB0aGUgbGVuZ3RoIG9mIHRoZSBtZXNzYWdlIE0sIGluIGJpdHMsIGlzIGxcbiAgdmFyIGwgPSB0aGlzLl9sZW4gKiA4XG5cbiAgLy8gQXBwZW5kIHRoZSBiaXQgMSB0byB0aGUgZW5kIG9mIHRoZSBtZXNzYWdlXG4gIHRoaXMuX2Jsb2NrW3RoaXMuX2xlbiAlIHRoaXMuX2Jsb2NrU2l6ZV0gPSAweDgwXG5cbiAgLy8gYW5kIHRoZW4gayB6ZXJvIGJpdHMsIHdoZXJlIGsgaXMgdGhlIHNtYWxsZXN0IG5vbi1uZWdhdGl2ZSBzb2x1dGlvbiB0byB0aGUgZXF1YXRpb24gKGwgKyAxICsgaykgPT09IGZpbmFsU2l6ZSBtb2QgYmxvY2tTaXplXG4gIHRoaXMuX2Jsb2NrLmZpbGwoMCwgdGhpcy5fbGVuICUgdGhpcy5fYmxvY2tTaXplICsgMSlcblxuICBpZiAobCAlICh0aGlzLl9ibG9ja1NpemUgKiA4KSA+PSB0aGlzLl9maW5hbFNpemUgKiA4KSB7XG4gICAgdGhpcy5fdXBkYXRlKHRoaXMuX2Jsb2NrKVxuICAgIHRoaXMuX2Jsb2NrLmZpbGwoMClcbiAgfVxuXG4gIC8vIHRvIHRoaXMgYXBwZW5kIHRoZSBibG9jayB3aGljaCBpcyBlcXVhbCB0byB0aGUgbnVtYmVyIGwgd3JpdHRlbiBpbiBiaW5hcnlcbiAgLy8gVE9ETzogaGFuZGxlIGNhc2Ugd2hlcmUgbCBpcyA+IE1hdGgucG93KDIsIDI5KVxuICB0aGlzLl9ibG9jay53cml0ZUludDMyQkUobCwgdGhpcy5fYmxvY2tTaXplIC0gNClcblxuICB2YXIgaGFzaCA9IHRoaXMuX3VwZGF0ZSh0aGlzLl9ibG9jaykgfHwgdGhpcy5faGFzaCgpXG5cbiAgcmV0dXJuIGVuYyA/IGhhc2gudG9TdHJpbmcoZW5jKSA6IGhhc2hcbn1cblxuSGFzaC5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdfdXBkYXRlIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3MnKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEhhc2hcbiIsInZhciBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTSEEgKGFsZ29yaXRobSkge1xuICBhbGdvcml0aG0gPSBhbGdvcml0aG0udG9Mb3dlckNhc2UoKVxuXG4gIHZhciBBbGdvcml0aG0gPSBleHBvcnRzW2FsZ29yaXRobV1cbiAgaWYgKCFBbGdvcml0aG0pIHRocm93IG5ldyBFcnJvcihhbGdvcml0aG0gKyAnIGlzIG5vdCBzdXBwb3J0ZWQgKHdlIGFjY2VwdCBwdWxsIHJlcXVlc3RzKScpXG5cbiAgcmV0dXJuIG5ldyBBbGdvcml0aG0oKVxufVxuXG5leHBvcnRzLnNoYSA9IHJlcXVpcmUoJy4vc2hhJylcbmV4cG9ydHMuc2hhMSA9IHJlcXVpcmUoJy4vc2hhMScpXG5leHBvcnRzLnNoYTIyNCA9IHJlcXVpcmUoJy4vc2hhMjI0JylcbmV4cG9ydHMuc2hhMjU2ID0gcmVxdWlyZSgnLi9zaGEyNTYnKVxuZXhwb3J0cy5zaGEzODQgPSByZXF1aXJlKCcuL3NoYTM4NCcpXG5leHBvcnRzLnNoYTUxMiA9IHJlcXVpcmUoJy4vc2hhNTEyJylcbiIsIi8qXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFNlY3VyZSBIYXNoIEFsZ29yaXRobSwgU0hBLTAsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgUFVCIDE4MC0xXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGRlcml2ZWQgZnJvbSBzaGExLmpzIG9mIHRoZSBzYW1lIHJlcG9zaXRvcnkuXG4gKiBUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIFNIQS0wIGFuZCBTSEEtMSBpcyBqdXN0IGEgYml0d2lzZSByb3RhdGUgbGVmdFxuICogb3BlcmF0aW9uIHdhcyBhZGRlZC5cbiAqL1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgSGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpXG5cbnZhciBXID0gbmV3IEFycmF5KDgwKVxuXG5mdW5jdGlvbiBTaGEgKCkge1xuICB0aGlzLmluaXQoKVxuICB0aGlzLl93ID0gV1xuXG4gIEhhc2guY2FsbCh0aGlzLCA2NCwgNTYpXG59XG5cbmluaGVyaXRzKFNoYSwgSGFzaClcblxuU2hhLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9hID0gMHg2NzQ1MjMwMSB8IDBcbiAgdGhpcy5fYiA9IDB4ZWZjZGFiODkgfCAwXG4gIHRoaXMuX2MgPSAweDk4YmFkY2ZlIHwgMFxuICB0aGlzLl9kID0gMHgxMDMyNTQ3NiB8IDBcbiAgdGhpcy5fZSA9IDB4YzNkMmUxZjAgfCAwXG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLypcbiAqIEJpdHdpc2Ugcm90YXRlIGEgMzItYml0IG51bWJlciB0byB0aGUgbGVmdC5cbiAqL1xuZnVuY3Rpb24gcm9sIChudW0sIGNudCkge1xuICByZXR1cm4gKG51bSA8PCBjbnQpIHwgKG51bSA+Pj4gKDMyIC0gY250KSlcbn1cblxuU2hhLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKE0pIHtcbiAgdmFyIFcgPSB0aGlzLl93XG5cbiAgdmFyIGEgPSB0aGlzLl9hXG4gIHZhciBiID0gdGhpcy5fYlxuICB2YXIgYyA9IHRoaXMuX2NcbiAgdmFyIGQgPSB0aGlzLl9kXG4gIHZhciBlID0gdGhpcy5fZVxuXG4gIHZhciBqID0gMFxuICB2YXIga1xuXG4gIC8qXG4gICAqIFNIQS0xIGhhcyBhIGJpdHdpc2Ugcm90YXRlIGxlZnQgb3BlcmF0aW9uLiBCdXQsIFNIQSBpcyBub3RcbiAgICogZnVuY3Rpb24gY2FsY1coKSB7IHJldHVybiByb2woV1tqIC0gM10gXiBXW2ogLSAgOF0gXiBXW2ogLSAxNF0gXiBXW2ogLSAxNl0sIDEpIH1cbiAgICovXG4gIGZ1bmN0aW9uIGNhbGNXICgpIHsgcmV0dXJuIFdbaiAtIDNdIF4gV1tqIC0gOF0gXiBXW2ogLSAxNF0gXiBXW2ogLSAxNl0gfVxuICBmdW5jdGlvbiBsb29wICh3LCBmKSB7XG4gICAgV1tqXSA9IHdcblxuICAgIHZhciB0ID0gcm9sKGEsIDUpICsgZiArIGUgKyB3ICsga1xuXG4gICAgZSA9IGRcbiAgICBkID0gY1xuICAgIGMgPSByb2woYiwgMzApXG4gICAgYiA9IGFcbiAgICBhID0gdFxuICAgIGorK1xuICB9XG5cbiAgayA9IDE1MTg1MDAyNDlcbiAgd2hpbGUgKGogPCAxNikgbG9vcChNLnJlYWRJbnQzMkJFKGogKiA0KSwgKGIgJiBjKSB8ICgofmIpICYgZCkpXG4gIHdoaWxlIChqIDwgMjApIGxvb3AoY2FsY1coKSwgKGIgJiBjKSB8ICgofmIpICYgZCkpXG4gIGsgPSAxODU5Nzc1MzkzXG4gIHdoaWxlIChqIDwgNDApIGxvb3AoY2FsY1coKSwgYiBeIGMgXiBkKVxuICBrID0gLTE4OTQwMDc1ODhcbiAgd2hpbGUgKGogPCA2MCkgbG9vcChjYWxjVygpLCAoYiAmIGMpIHwgKGIgJiBkKSB8IChjICYgZCkpXG4gIGsgPSAtODk5NDk3NTE0XG4gIHdoaWxlIChqIDwgODApIGxvb3AoY2FsY1coKSwgYiBeIGMgXiBkKVxuXG4gIHRoaXMuX2EgPSAoYSArIHRoaXMuX2EpIHwgMFxuICB0aGlzLl9iID0gKGIgKyB0aGlzLl9iKSB8IDBcbiAgdGhpcy5fYyA9IChjICsgdGhpcy5fYykgfCAwXG4gIHRoaXMuX2QgPSAoZCArIHRoaXMuX2QpIHwgMFxuICB0aGlzLl9lID0gKGUgKyB0aGlzLl9lKSB8IDBcbn1cblxuU2hhLnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBuZXcgQnVmZmVyKDIwKVxuXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2EgfCAwLCAwKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9iIHwgMCwgNClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYyB8IDAsIDgpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2QgfCAwLCAxMilcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZSB8IDAsIDE2KVxuXG4gIHJldHVybiBIXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2hhXG5cbiIsIi8qXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFNlY3VyZSBIYXNoIEFsZ29yaXRobSwgU0hBLTEsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgUFVCIDE4MC0xXG4gKiBWZXJzaW9uIDIuMWEgQ29weXJpZ2h0IFBhdWwgSm9obnN0b24gMjAwMCAtIDIwMDIuXG4gKiBPdGhlciBjb250cmlidXRvcnM6IEdyZWcgSG9sdCwgQW5kcmV3IEtlcGVydCwgWWRuYXIsIExvc3RpbmV0XG4gKiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQlNEIExpY2Vuc2VcbiAqIFNlZSBodHRwOi8vcGFqaG9tZS5vcmcudWsvY3J5cHQvbWQ1IGZvciBkZXRhaWxzLlxuICovXG5cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBIYXNoID0gcmVxdWlyZSgnLi9oYXNoJylcblxudmFyIFcgPSBuZXcgQXJyYXkoODApXG5cbmZ1bmN0aW9uIFNoYTEgKCkge1xuICB0aGlzLmluaXQoKVxuICB0aGlzLl93ID0gV1xuXG4gIEhhc2guY2FsbCh0aGlzLCA2NCwgNTYpXG59XG5cbmluaGVyaXRzKFNoYTEsIEhhc2gpXG5cblNoYTEucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2EgPSAweDY3NDUyMzAxIHwgMFxuICB0aGlzLl9iID0gMHhlZmNkYWI4OSB8IDBcbiAgdGhpcy5fYyA9IDB4OThiYWRjZmUgfCAwXG4gIHRoaXMuX2QgPSAweDEwMzI1NDc2IHwgMFxuICB0aGlzLl9lID0gMHhjM2QyZTFmMCB8IDBcblxuICByZXR1cm4gdGhpc1xufVxuXG4vKlxuICogQml0d2lzZSByb3RhdGUgYSAzMi1iaXQgbnVtYmVyIHRvIHRoZSBsZWZ0LlxuICovXG5mdW5jdGlvbiByb2wgKG51bSwgY250KSB7XG4gIHJldHVybiAobnVtIDw8IGNudCkgfCAobnVtID4+PiAoMzIgLSBjbnQpKVxufVxuXG5TaGExLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKE0pIHtcbiAgdmFyIFcgPSB0aGlzLl93XG5cbiAgdmFyIGEgPSB0aGlzLl9hXG4gIHZhciBiID0gdGhpcy5fYlxuICB2YXIgYyA9IHRoaXMuX2NcbiAgdmFyIGQgPSB0aGlzLl9kXG4gIHZhciBlID0gdGhpcy5fZVxuXG4gIHZhciBqID0gMFxuICB2YXIga1xuXG4gIGZ1bmN0aW9uIGNhbGNXICgpIHsgcmV0dXJuIHJvbChXW2ogLSAzXSBeIFdbaiAtIDhdIF4gV1tqIC0gMTRdIF4gV1tqIC0gMTZdLCAxKSB9XG4gIGZ1bmN0aW9uIGxvb3AgKHcsIGYpIHtcbiAgICBXW2pdID0gd1xuXG4gICAgdmFyIHQgPSByb2woYSwgNSkgKyBmICsgZSArIHcgKyBrXG5cbiAgICBlID0gZFxuICAgIGQgPSBjXG4gICAgYyA9IHJvbChiLCAzMClcbiAgICBiID0gYVxuICAgIGEgPSB0XG4gICAgaisrXG4gIH1cblxuICBrID0gMTUxODUwMDI0OVxuICB3aGlsZSAoaiA8IDE2KSBsb29wKE0ucmVhZEludDMyQkUoaiAqIDQpLCAoYiAmIGMpIHwgKCh+YikgJiBkKSlcbiAgd2hpbGUgKGogPCAyMCkgbG9vcChjYWxjVygpLCAoYiAmIGMpIHwgKCh+YikgJiBkKSlcbiAgayA9IDE4NTk3NzUzOTNcbiAgd2hpbGUgKGogPCA0MCkgbG9vcChjYWxjVygpLCBiIF4gYyBeIGQpXG4gIGsgPSAtMTg5NDAwNzU4OFxuICB3aGlsZSAoaiA8IDYwKSBsb29wKGNhbGNXKCksIChiICYgYykgfCAoYiAmIGQpIHwgKGMgJiBkKSlcbiAgayA9IC04OTk0OTc1MTRcbiAgd2hpbGUgKGogPCA4MCkgbG9vcChjYWxjVygpLCBiIF4gYyBeIGQpXG5cbiAgdGhpcy5fYSA9IChhICsgdGhpcy5fYSkgfCAwXG4gIHRoaXMuX2IgPSAoYiArIHRoaXMuX2IpIHwgMFxuICB0aGlzLl9jID0gKGMgKyB0aGlzLl9jKSB8IDBcbiAgdGhpcy5fZCA9IChkICsgdGhpcy5fZCkgfCAwXG4gIHRoaXMuX2UgPSAoZSArIHRoaXMuX2UpIHwgMFxufVxuXG5TaGExLnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBuZXcgQnVmZmVyKDIwKVxuXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2EgfCAwLCAwKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9iIHwgMCwgNClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYyB8IDAsIDgpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2QgfCAwLCAxMilcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZSB8IDAsIDE2KVxuXG4gIHJldHVybiBIXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2hhMVxuIiwiLyoqXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFNlY3VyZSBIYXNoIEFsZ29yaXRobSwgU0hBLTI1NiwgYXMgZGVmaW5lZFxuICogaW4gRklQUyAxODAtMlxuICogVmVyc2lvbiAyLjItYmV0YSBDb3B5cmlnaHQgQW5nZWwgTWFyaW4sIFBhdWwgSm9obnN0b24gMjAwMCAtIDIwMDkuXG4gKiBPdGhlciBjb250cmlidXRvcnM6IEdyZWcgSG9sdCwgQW5kcmV3IEtlcGVydCwgWWRuYXIsIExvc3RpbmV0XG4gKlxuICovXG5cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBTaGEyNTYgPSByZXF1aXJlKCcuL3NoYTI1NicpXG52YXIgSGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpXG5cbnZhciBXID0gbmV3IEFycmF5KDY0KVxuXG5mdW5jdGlvbiBTaGEyMjQgKCkge1xuICB0aGlzLmluaXQoKVxuXG4gIHRoaXMuX3cgPSBXIC8vIG5ldyBBcnJheSg2NClcblxuICBIYXNoLmNhbGwodGhpcywgNjQsIDU2KVxufVxuXG5pbmhlcml0cyhTaGEyMjQsIFNoYTI1NilcblxuU2hhMjI0LnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9hID0gMHhjMTA1OWVkOCB8IDBcbiAgdGhpcy5fYiA9IDB4MzY3Y2Q1MDcgfCAwXG4gIHRoaXMuX2MgPSAweDMwNzBkZDE3IHwgMFxuICB0aGlzLl9kID0gMHhmNzBlNTkzOSB8IDBcbiAgdGhpcy5fZSA9IDB4ZmZjMDBiMzEgfCAwXG4gIHRoaXMuX2YgPSAweDY4NTgxNTExIHwgMFxuICB0aGlzLl9nID0gMHg2NGY5OGZhNyB8IDBcbiAgdGhpcy5faCA9IDB4YmVmYTRmYTQgfCAwXG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuU2hhMjI0LnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBuZXcgQnVmZmVyKDI4KVxuXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2EsIDApXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2IsIDQpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2MsIDgpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2QsIDEyKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9lLCAxNilcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZiwgMjApXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2csIDI0KVxuXG4gIHJldHVybiBIXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2hhMjI0XG4iLCIvKipcbiAqIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU2VjdXJlIEhhc2ggQWxnb3JpdGhtLCBTSEEtMjU2LCBhcyBkZWZpbmVkXG4gKiBpbiBGSVBTIDE4MC0yXG4gKiBWZXJzaW9uIDIuMi1iZXRhIENvcHlyaWdodCBBbmdlbCBNYXJpbiwgUGF1bCBKb2huc3RvbiAyMDAwIC0gMjAwOS5cbiAqIE90aGVyIGNvbnRyaWJ1dG9yczogR3JlZyBIb2x0LCBBbmRyZXcgS2VwZXJ0LCBZZG5hciwgTG9zdGluZXRcbiAqXG4gKi9cblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKVxuXG52YXIgSyA9IFtcbiAgMHg0MjhBMkY5OCwgMHg3MTM3NDQ5MSwgMHhCNUMwRkJDRiwgMHhFOUI1REJBNSxcbiAgMHgzOTU2QzI1QiwgMHg1OUYxMTFGMSwgMHg5MjNGODJBNCwgMHhBQjFDNUVENSxcbiAgMHhEODA3QUE5OCwgMHgxMjgzNUIwMSwgMHgyNDMxODVCRSwgMHg1NTBDN0RDMyxcbiAgMHg3MkJFNUQ3NCwgMHg4MERFQjFGRSwgMHg5QkRDMDZBNywgMHhDMTlCRjE3NCxcbiAgMHhFNDlCNjlDMSwgMHhFRkJFNDc4NiwgMHgwRkMxOURDNiwgMHgyNDBDQTFDQyxcbiAgMHgyREU5MkM2RiwgMHg0QTc0ODRBQSwgMHg1Q0IwQTlEQywgMHg3NkY5ODhEQSxcbiAgMHg5ODNFNTE1MiwgMHhBODMxQzY2RCwgMHhCMDAzMjdDOCwgMHhCRjU5N0ZDNyxcbiAgMHhDNkUwMEJGMywgMHhENUE3OTE0NywgMHgwNkNBNjM1MSwgMHgxNDI5Mjk2NyxcbiAgMHgyN0I3MEE4NSwgMHgyRTFCMjEzOCwgMHg0RDJDNkRGQywgMHg1MzM4MEQxMyxcbiAgMHg2NTBBNzM1NCwgMHg3NjZBMEFCQiwgMHg4MUMyQzkyRSwgMHg5MjcyMkM4NSxcbiAgMHhBMkJGRThBMSwgMHhBODFBNjY0QiwgMHhDMjRCOEI3MCwgMHhDNzZDNTFBMyxcbiAgMHhEMTkyRTgxOSwgMHhENjk5MDYyNCwgMHhGNDBFMzU4NSwgMHgxMDZBQTA3MCxcbiAgMHgxOUE0QzExNiwgMHgxRTM3NkMwOCwgMHgyNzQ4Nzc0QywgMHgzNEIwQkNCNSxcbiAgMHgzOTFDMENCMywgMHg0RUQ4QUE0QSwgMHg1QjlDQ0E0RiwgMHg2ODJFNkZGMyxcbiAgMHg3NDhGODJFRSwgMHg3OEE1NjM2RiwgMHg4NEM4NzgxNCwgMHg4Q0M3MDIwOCxcbiAgMHg5MEJFRkZGQSwgMHhBNDUwNkNFQiwgMHhCRUY5QTNGNywgMHhDNjcxNzhGMlxuXVxuXG52YXIgVyA9IG5ldyBBcnJheSg2NClcblxuZnVuY3Rpb24gU2hhMjU2ICgpIHtcbiAgdGhpcy5pbml0KClcblxuICB0aGlzLl93ID0gVyAvLyBuZXcgQXJyYXkoNjQpXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDY0LCA1Nilcbn1cblxuaW5oZXJpdHMoU2hhMjU2LCBIYXNoKVxuXG5TaGEyNTYucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2EgPSAweDZhMDllNjY3IHwgMFxuICB0aGlzLl9iID0gMHhiYjY3YWU4NSB8IDBcbiAgdGhpcy5fYyA9IDB4M2M2ZWYzNzIgfCAwXG4gIHRoaXMuX2QgPSAweGE1NGZmNTNhIHwgMFxuICB0aGlzLl9lID0gMHg1MTBlNTI3ZiB8IDBcbiAgdGhpcy5fZiA9IDB4OWIwNTY4OGMgfCAwXG4gIHRoaXMuX2cgPSAweDFmODNkOWFiIHwgMFxuICB0aGlzLl9oID0gMHg1YmUwY2QxOSB8IDBcblxuICByZXR1cm4gdGhpc1xufVxuXG5mdW5jdGlvbiBDaCAoeCwgeSwgeikge1xuICByZXR1cm4geiBeICh4ICYgKHkgXiB6KSlcbn1cblxuZnVuY3Rpb24gTWFqICh4LCB5LCB6KSB7XG4gIHJldHVybiAoeCAmIHkpIHwgKHogJiAoeCB8IHkpKVxufVxuXG5mdW5jdGlvbiBTaWdtYTAgKHgpIHtcbiAgcmV0dXJuICh4ID4+PiAyIHwgeCA8PCAzMCkgXiAoeCA+Pj4gMTMgfCB4IDw8IDE5KSBeICh4ID4+PiAyMiB8IHggPDwgMTApXG59XG5cbmZ1bmN0aW9uIFNpZ21hMSAoeCkge1xuICByZXR1cm4gKHggPj4+IDYgfCB4IDw8IDI2KSBeICh4ID4+PiAxMSB8IHggPDwgMjEpIF4gKHggPj4+IDI1IHwgeCA8PCA3KVxufVxuXG5mdW5jdGlvbiBHYW1tYTAgKHgpIHtcbiAgcmV0dXJuICh4ID4+PiA3IHwgeCA8PCAyNSkgXiAoeCA+Pj4gMTggfCB4IDw8IDE0KSBeICh4ID4+PiAzKVxufVxuXG5mdW5jdGlvbiBHYW1tYTEgKHgpIHtcbiAgcmV0dXJuICh4ID4+PiAxNyB8IHggPDwgMTUpIF4gKHggPj4+IDE5IHwgeCA8PCAxMykgXiAoeCA+Pj4gMTApXG59XG5cblNoYTI1Ni5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChNKSB7XG4gIHZhciBXID0gdGhpcy5fd1xuXG4gIHZhciBhID0gdGhpcy5fYSB8IDBcbiAgdmFyIGIgPSB0aGlzLl9iIHwgMFxuICB2YXIgYyA9IHRoaXMuX2MgfCAwXG4gIHZhciBkID0gdGhpcy5fZCB8IDBcbiAgdmFyIGUgPSB0aGlzLl9lIHwgMFxuICB2YXIgZiA9IHRoaXMuX2YgfCAwXG4gIHZhciBnID0gdGhpcy5fZyB8IDBcbiAgdmFyIGggPSB0aGlzLl9oIHwgMFxuXG4gIHZhciBqID0gMFxuXG4gIGZ1bmN0aW9uIGNhbGNXICgpIHsgcmV0dXJuIEdhbW1hMShXW2ogLSAyXSkgKyBXW2ogLSA3XSArIEdhbW1hMChXW2ogLSAxNV0pICsgV1tqIC0gMTZdIH1cbiAgZnVuY3Rpb24gbG9vcCAodykge1xuICAgIFdbal0gPSB3XG5cbiAgICB2YXIgVDEgPSBoICsgU2lnbWExKGUpICsgQ2goZSwgZiwgZykgKyBLW2pdICsgd1xuICAgIHZhciBUMiA9IFNpZ21hMChhKSArIE1haihhLCBiLCBjKVxuXG4gICAgaCA9IGdcbiAgICBnID0gZlxuICAgIGYgPSBlXG4gICAgZSA9IGQgKyBUMVxuICAgIGQgPSBjXG4gICAgYyA9IGJcbiAgICBiID0gYVxuICAgIGEgPSBUMSArIFQyXG5cbiAgICBqKytcbiAgfVxuXG4gIHdoaWxlIChqIDwgMTYpIGxvb3AoTS5yZWFkSW50MzJCRShqICogNCkpXG4gIHdoaWxlIChqIDwgNjQpIGxvb3AoY2FsY1coKSlcblxuICB0aGlzLl9hID0gKGEgKyB0aGlzLl9hKSB8IDBcbiAgdGhpcy5fYiA9IChiICsgdGhpcy5fYikgfCAwXG4gIHRoaXMuX2MgPSAoYyArIHRoaXMuX2MpIHwgMFxuICB0aGlzLl9kID0gKGQgKyB0aGlzLl9kKSB8IDBcbiAgdGhpcy5fZSA9IChlICsgdGhpcy5fZSkgfCAwXG4gIHRoaXMuX2YgPSAoZiArIHRoaXMuX2YpIHwgMFxuICB0aGlzLl9nID0gKGcgKyB0aGlzLl9nKSB8IDBcbiAgdGhpcy5faCA9IChoICsgdGhpcy5faCkgfCAwXG59XG5cblNoYTI1Ni5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gbmV3IEJ1ZmZlcigzMilcblxuICBILndyaXRlSW50MzJCRSh0aGlzLl9hLCAwKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9iLCA0KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9jLCA4KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9kLCAxMilcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZSwgMTYpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2YsIDIwKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9nLCAyNClcbiAgSC53cml0ZUludDMyQkUodGhpcy5faCwgMjgpXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGEyNTZcbiIsInZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBTSEE1MTIgPSByZXF1aXJlKCcuL3NoYTUxMicpXG52YXIgSGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpXG5cbnZhciBXID0gbmV3IEFycmF5KDE2MClcblxuZnVuY3Rpb24gU2hhMzg0ICgpIHtcbiAgdGhpcy5pbml0KClcbiAgdGhpcy5fdyA9IFdcblxuICBIYXNoLmNhbGwodGhpcywgMTI4LCAxMTIpXG59XG5cbmluaGVyaXRzKFNoYTM4NCwgU0hBNTEyKVxuXG5TaGEzODQucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2EgPSAweGNiYmI5ZDVkIHwgMFxuICB0aGlzLl9iID0gMHg2MjlhMjkyYSB8IDBcbiAgdGhpcy5fYyA9IDB4OTE1OTAxNWEgfCAwXG4gIHRoaXMuX2QgPSAweDE1MmZlY2Q4IHwgMFxuICB0aGlzLl9lID0gMHg2NzMzMjY2NyB8IDBcbiAgdGhpcy5fZiA9IDB4OGViNDRhODcgfCAwXG4gIHRoaXMuX2cgPSAweGRiMGMyZTBkIHwgMFxuICB0aGlzLl9oID0gMHg0N2I1NDgxZCB8IDBcblxuICB0aGlzLl9hbCA9IDB4YzEwNTllZDggfCAwXG4gIHRoaXMuX2JsID0gMHgzNjdjZDUwNyB8IDBcbiAgdGhpcy5fY2wgPSAweDMwNzBkZDE3IHwgMFxuICB0aGlzLl9kbCA9IDB4ZjcwZTU5MzkgfCAwXG4gIHRoaXMuX2VsID0gMHhmZmMwMGIzMSB8IDBcbiAgdGhpcy5fZmwgPSAweDY4NTgxNTExIHwgMFxuICB0aGlzLl9nbCA9IDB4NjRmOThmYTcgfCAwXG4gIHRoaXMuX2hsID0gMHhiZWZhNGZhNCB8IDBcblxuICByZXR1cm4gdGhpc1xufVxuXG5TaGEzODQucHJvdG90eXBlLl9oYXNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgSCA9IG5ldyBCdWZmZXIoNDgpXG5cbiAgZnVuY3Rpb24gd3JpdGVJbnQ2NEJFIChoLCBsLCBvZmZzZXQpIHtcbiAgICBILndyaXRlSW50MzJCRShoLCBvZmZzZXQpXG4gICAgSC53cml0ZUludDMyQkUobCwgb2Zmc2V0ICsgNClcbiAgfVxuXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9hLCB0aGlzLl9hbCwgMClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2IsIHRoaXMuX2JsLCA4KVxuICB3cml0ZUludDY0QkUodGhpcy5fYywgdGhpcy5fY2wsIDE2KVxuICB3cml0ZUludDY0QkUodGhpcy5fZCwgdGhpcy5fZGwsIDI0KVxuICB3cml0ZUludDY0QkUodGhpcy5fZSwgdGhpcy5fZWwsIDMyKVxuICB3cml0ZUludDY0QkUodGhpcy5fZiwgdGhpcy5fZmwsIDQwKVxuXG4gIHJldHVybiBIXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2hhMzg0XG4iLCJ2YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgSGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpXG5cbnZhciBLID0gW1xuICAweDQyOGEyZjk4LCAweGQ3MjhhZTIyLCAweDcxMzc0NDkxLCAweDIzZWY2NWNkLFxuICAweGI1YzBmYmNmLCAweGVjNGQzYjJmLCAweGU5YjVkYmE1LCAweDgxODlkYmJjLFxuICAweDM5NTZjMjViLCAweGYzNDhiNTM4LCAweDU5ZjExMWYxLCAweGI2MDVkMDE5LFxuICAweDkyM2Y4MmE0LCAweGFmMTk0ZjliLCAweGFiMWM1ZWQ1LCAweGRhNmQ4MTE4LFxuICAweGQ4MDdhYTk4LCAweGEzMDMwMjQyLCAweDEyODM1YjAxLCAweDQ1NzA2ZmJlLFxuICAweDI0MzE4NWJlLCAweDRlZTRiMjhjLCAweDU1MGM3ZGMzLCAweGQ1ZmZiNGUyLFxuICAweDcyYmU1ZDc0LCAweGYyN2I4OTZmLCAweDgwZGViMWZlLCAweDNiMTY5NmIxLFxuICAweDliZGMwNmE3LCAweDI1YzcxMjM1LCAweGMxOWJmMTc0LCAweGNmNjkyNjk0LFxuICAweGU0OWI2OWMxLCAweDllZjE0YWQyLCAweGVmYmU0Nzg2LCAweDM4NGYyNWUzLFxuICAweDBmYzE5ZGM2LCAweDhiOGNkNWI1LCAweDI0MGNhMWNjLCAweDc3YWM5YzY1LFxuICAweDJkZTkyYzZmLCAweDU5MmIwMjc1LCAweDRhNzQ4NGFhLCAweDZlYTZlNDgzLFxuICAweDVjYjBhOWRjLCAweGJkNDFmYmQ0LCAweDc2Zjk4OGRhLCAweDgzMTE1M2I1LFxuICAweDk4M2U1MTUyLCAweGVlNjZkZmFiLCAweGE4MzFjNjZkLCAweDJkYjQzMjEwLFxuICAweGIwMDMyN2M4LCAweDk4ZmIyMTNmLCAweGJmNTk3ZmM3LCAweGJlZWYwZWU0LFxuICAweGM2ZTAwYmYzLCAweDNkYTg4ZmMyLCAweGQ1YTc5MTQ3LCAweDkzMGFhNzI1LFxuICAweDA2Y2E2MzUxLCAweGUwMDM4MjZmLCAweDE0MjkyOTY3LCAweDBhMGU2ZTcwLFxuICAweDI3YjcwYTg1LCAweDQ2ZDIyZmZjLCAweDJlMWIyMTM4LCAweDVjMjZjOTI2LFxuICAweDRkMmM2ZGZjLCAweDVhYzQyYWVkLCAweDUzMzgwZDEzLCAweDlkOTViM2RmLFxuICAweDY1MGE3MzU0LCAweDhiYWY2M2RlLCAweDc2NmEwYWJiLCAweDNjNzdiMmE4LFxuICAweDgxYzJjOTJlLCAweDQ3ZWRhZWU2LCAweDkyNzIyYzg1LCAweDE0ODIzNTNiLFxuICAweGEyYmZlOGExLCAweDRjZjEwMzY0LCAweGE4MWE2NjRiLCAweGJjNDIzMDAxLFxuICAweGMyNGI4YjcwLCAweGQwZjg5NzkxLCAweGM3NmM1MWEzLCAweDA2NTRiZTMwLFxuICAweGQxOTJlODE5LCAweGQ2ZWY1MjE4LCAweGQ2OTkwNjI0LCAweDU1NjVhOTEwLFxuICAweGY0MGUzNTg1LCAweDU3NzEyMDJhLCAweDEwNmFhMDcwLCAweDMyYmJkMWI4LFxuICAweDE5YTRjMTE2LCAweGI4ZDJkMGM4LCAweDFlMzc2YzA4LCAweDUxNDFhYjUzLFxuICAweDI3NDg3NzRjLCAweGRmOGVlYjk5LCAweDM0YjBiY2I1LCAweGUxOWI0OGE4LFxuICAweDM5MWMwY2IzLCAweGM1Yzk1YTYzLCAweDRlZDhhYTRhLCAweGUzNDE4YWNiLFxuICAweDViOWNjYTRmLCAweDc3NjNlMzczLCAweDY4MmU2ZmYzLCAweGQ2YjJiOGEzLFxuICAweDc0OGY4MmVlLCAweDVkZWZiMmZjLCAweDc4YTU2MzZmLCAweDQzMTcyZjYwLFxuICAweDg0Yzg3ODE0LCAweGExZjBhYjcyLCAweDhjYzcwMjA4LCAweDFhNjQzOWVjLFxuICAweDkwYmVmZmZhLCAweDIzNjMxZTI4LCAweGE0NTA2Y2ViLCAweGRlODJiZGU5LFxuICAweGJlZjlhM2Y3LCAweGIyYzY3OTE1LCAweGM2NzE3OGYyLCAweGUzNzI1MzJiLFxuICAweGNhMjczZWNlLCAweGVhMjY2MTljLCAweGQxODZiOGM3LCAweDIxYzBjMjA3LFxuICAweGVhZGE3ZGQ2LCAweGNkZTBlYjFlLCAweGY1N2Q0ZjdmLCAweGVlNmVkMTc4LFxuICAweDA2ZjA2N2FhLCAweDcyMTc2ZmJhLCAweDBhNjM3ZGM1LCAweGEyYzg5OGE2LFxuICAweDExM2Y5ODA0LCAweGJlZjkwZGFlLCAweDFiNzEwYjM1LCAweDEzMWM0NzFiLFxuICAweDI4ZGI3N2Y1LCAweDIzMDQ3ZDg0LCAweDMyY2FhYjdiLCAweDQwYzcyNDkzLFxuICAweDNjOWViZTBhLCAweDE1YzliZWJjLCAweDQzMWQ2N2M0LCAweDljMTAwZDRjLFxuICAweDRjYzVkNGJlLCAweGNiM2U0MmI2LCAweDU5N2YyOTljLCAweGZjNjU3ZTJhLFxuICAweDVmY2I2ZmFiLCAweDNhZDZmYWVjLCAweDZjNDQxOThjLCAweDRhNDc1ODE3XG5dXG5cbnZhciBXID0gbmV3IEFycmF5KDE2MClcblxuZnVuY3Rpb24gU2hhNTEyICgpIHtcbiAgdGhpcy5pbml0KClcbiAgdGhpcy5fdyA9IFdcblxuICBIYXNoLmNhbGwodGhpcywgMTI4LCAxMTIpXG59XG5cbmluaGVyaXRzKFNoYTUxMiwgSGFzaClcblxuU2hhNTEyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9hID0gMHg2YTA5ZTY2NyB8IDBcbiAgdGhpcy5fYiA9IDB4YmI2N2FlODUgfCAwXG4gIHRoaXMuX2MgPSAweDNjNmVmMzcyIHwgMFxuICB0aGlzLl9kID0gMHhhNTRmZjUzYSB8IDBcbiAgdGhpcy5fZSA9IDB4NTEwZTUyN2YgfCAwXG4gIHRoaXMuX2YgPSAweDliMDU2ODhjIHwgMFxuICB0aGlzLl9nID0gMHgxZjgzZDlhYiB8IDBcbiAgdGhpcy5faCA9IDB4NWJlMGNkMTkgfCAwXG5cbiAgdGhpcy5fYWwgPSAweGYzYmNjOTA4IHwgMFxuICB0aGlzLl9ibCA9IDB4ODRjYWE3M2IgfCAwXG4gIHRoaXMuX2NsID0gMHhmZTk0ZjgyYiB8IDBcbiAgdGhpcy5fZGwgPSAweDVmMWQzNmYxIHwgMFxuICB0aGlzLl9lbCA9IDB4YWRlNjgyZDEgfCAwXG4gIHRoaXMuX2ZsID0gMHgyYjNlNmMxZiB8IDBcbiAgdGhpcy5fZ2wgPSAweGZiNDFiZDZiIHwgMFxuICB0aGlzLl9obCA9IDB4MTM3ZTIxNzkgfCAwXG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gQ2ggKHgsIHksIHopIHtcbiAgcmV0dXJuIHogXiAoeCAmICh5IF4geikpXG59XG5cbmZ1bmN0aW9uIE1haiAoeCwgeSwgeikge1xuICByZXR1cm4gKHggJiB5KSB8ICh6ICYgKHggfCB5KSlcbn1cblxuZnVuY3Rpb24gU2lnbWEwICh4LCB4bCkge1xuICByZXR1cm4gKHggPj4+IDI4IHwgeGwgPDwgNCkgXiAoeGwgPj4+IDIgfCB4IDw8IDMwKSBeICh4bCA+Pj4gNyB8IHggPDwgMjUpXG59XG5cbmZ1bmN0aW9uIFNpZ21hMSAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxNCB8IHhsIDw8IDE4KSBeICh4ID4+PiAxOCB8IHhsIDw8IDE0KSBeICh4bCA+Pj4gOSB8IHggPDwgMjMpXG59XG5cbmZ1bmN0aW9uIEdhbW1hMCAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxIHwgeGwgPDwgMzEpIF4gKHggPj4+IDggfCB4bCA8PCAyNCkgXiAoeCA+Pj4gNylcbn1cblxuZnVuY3Rpb24gR2FtbWEwbCAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxIHwgeGwgPDwgMzEpIF4gKHggPj4+IDggfCB4bCA8PCAyNCkgXiAoeCA+Pj4gNyB8IHhsIDw8IDI1KVxufVxuXG5mdW5jdGlvbiBHYW1tYTEgKHgsIHhsKSB7XG4gIHJldHVybiAoeCA+Pj4gMTkgfCB4bCA8PCAxMykgXiAoeGwgPj4+IDI5IHwgeCA8PCAzKSBeICh4ID4+PiA2KVxufVxuXG5mdW5jdGlvbiBHYW1tYTFsICh4LCB4bCkge1xuICByZXR1cm4gKHggPj4+IDE5IHwgeGwgPDwgMTMpIF4gKHhsID4+PiAyOSB8IHggPDwgMykgXiAoeCA+Pj4gNiB8IHhsIDw8IDI2KVxufVxuXG5TaGE1MTIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoTSkge1xuICB2YXIgVyA9IHRoaXMuX3dcblxuICB2YXIgYSA9IHRoaXMuX2EgfCAwXG4gIHZhciBiID0gdGhpcy5fYiB8IDBcbiAgdmFyIGMgPSB0aGlzLl9jIHwgMFxuICB2YXIgZCA9IHRoaXMuX2QgfCAwXG4gIHZhciBlID0gdGhpcy5fZSB8IDBcbiAgdmFyIGYgPSB0aGlzLl9mIHwgMFxuICB2YXIgZyA9IHRoaXMuX2cgfCAwXG4gIHZhciBoID0gdGhpcy5faCB8IDBcblxuICB2YXIgYWwgPSB0aGlzLl9hbCB8IDBcbiAgdmFyIGJsID0gdGhpcy5fYmwgfCAwXG4gIHZhciBjbCA9IHRoaXMuX2NsIHwgMFxuICB2YXIgZGwgPSB0aGlzLl9kbCB8IDBcbiAgdmFyIGVsID0gdGhpcy5fZWwgfCAwXG4gIHZhciBmbCA9IHRoaXMuX2ZsIHwgMFxuICB2YXIgZ2wgPSB0aGlzLl9nbCB8IDBcbiAgdmFyIGhsID0gdGhpcy5faGwgfCAwXG5cbiAgdmFyIGkgPSAwXG4gIHZhciBqID0gMFxuICB2YXIgV2ksIFdpbFxuICBmdW5jdGlvbiBjYWxjVyAoKSB7XG4gICAgdmFyIHggPSBXW2ogLSAxNSAqIDJdXG4gICAgdmFyIHhsID0gV1tqIC0gMTUgKiAyICsgMV1cbiAgICB2YXIgZ2FtbWEwID0gR2FtbWEwKHgsIHhsKVxuICAgIHZhciBnYW1tYTBsID0gR2FtbWEwbCh4bCwgeClcblxuICAgIHggPSBXW2ogLSAyICogMl1cbiAgICB4bCA9IFdbaiAtIDIgKiAyICsgMV1cbiAgICB2YXIgZ2FtbWExID0gR2FtbWExKHgsIHhsKVxuICAgIHZhciBnYW1tYTFsID0gR2FtbWExbCh4bCwgeClcblxuICAgIC8vIFdbaV0gPSBnYW1tYTAgKyBXW2kgLSA3XSArIGdhbW1hMSArIFdbaSAtIDE2XVxuICAgIHZhciBXaTcgPSBXW2ogLSA3ICogMl1cbiAgICB2YXIgV2k3bCA9IFdbaiAtIDcgKiAyICsgMV1cblxuICAgIHZhciBXaTE2ID0gV1tqIC0gMTYgKiAyXVxuICAgIHZhciBXaTE2bCA9IFdbaiAtIDE2ICogMiArIDFdXG5cbiAgICBXaWwgPSBnYW1tYTBsICsgV2k3bFxuICAgIFdpID0gZ2FtbWEwICsgV2k3ICsgKChXaWwgPj4+IDApIDwgKGdhbW1hMGwgPj4+IDApID8gMSA6IDApXG4gICAgV2lsID0gV2lsICsgZ2FtbWExbFxuICAgIFdpID0gV2kgKyBnYW1tYTEgKyAoKFdpbCA+Pj4gMCkgPCAoZ2FtbWExbCA+Pj4gMCkgPyAxIDogMClcbiAgICBXaWwgPSBXaWwgKyBXaTE2bFxuICAgIFdpID0gV2kgKyBXaTE2ICsgKChXaWwgPj4+IDApIDwgKFdpMTZsID4+PiAwKSA/IDEgOiAwKVxuICB9XG5cbiAgZnVuY3Rpb24gbG9vcCAoKSB7XG4gICAgV1tqXSA9IFdpXG4gICAgV1tqICsgMV0gPSBXaWxcblxuICAgIHZhciBtYWogPSBNYWooYSwgYiwgYylcbiAgICB2YXIgbWFqbCA9IE1haihhbCwgYmwsIGNsKVxuXG4gICAgdmFyIHNpZ21hMGggPSBTaWdtYTAoYSwgYWwpXG4gICAgdmFyIHNpZ21hMGwgPSBTaWdtYTAoYWwsIGEpXG4gICAgdmFyIHNpZ21hMWggPSBTaWdtYTEoZSwgZWwpXG4gICAgdmFyIHNpZ21hMWwgPSBTaWdtYTEoZWwsIGUpXG5cbiAgICAvLyB0MSA9IGggKyBzaWdtYTEgKyBjaCArIEtbaV0gKyBXW2ldXG4gICAgdmFyIEtpID0gS1tqXVxuICAgIHZhciBLaWwgPSBLW2ogKyAxXVxuXG4gICAgdmFyIGNoID0gQ2goZSwgZiwgZylcbiAgICB2YXIgY2hsID0gQ2goZWwsIGZsLCBnbClcblxuICAgIHZhciB0MWwgPSBobCArIHNpZ21hMWxcbiAgICB2YXIgdDEgPSBoICsgc2lnbWExaCArICgodDFsID4+PiAwKSA8IChobCA+Pj4gMCkgPyAxIDogMClcbiAgICB0MWwgPSB0MWwgKyBjaGxcbiAgICB0MSA9IHQxICsgY2ggKyAoKHQxbCA+Pj4gMCkgPCAoY2hsID4+PiAwKSA/IDEgOiAwKVxuICAgIHQxbCA9IHQxbCArIEtpbFxuICAgIHQxID0gdDEgKyBLaSArICgodDFsID4+PiAwKSA8IChLaWwgPj4+IDApID8gMSA6IDApXG4gICAgdDFsID0gdDFsICsgV2lsXG4gICAgdDEgPSB0MSArIFdpICsgKCh0MWwgPj4+IDApIDwgKFdpbCA+Pj4gMCkgPyAxIDogMClcblxuICAgIC8vIHQyID0gc2lnbWEwICsgbWFqXG4gICAgdmFyIHQybCA9IHNpZ21hMGwgKyBtYWpsXG4gICAgdmFyIHQyID0gc2lnbWEwaCArIG1haiArICgodDJsID4+PiAwKSA8IChzaWdtYTBsID4+PiAwKSA/IDEgOiAwKVxuXG4gICAgaCA9IGdcbiAgICBobCA9IGdsXG4gICAgZyA9IGZcbiAgICBnbCA9IGZsXG4gICAgZiA9IGVcbiAgICBmbCA9IGVsXG4gICAgZWwgPSAoZGwgKyB0MWwpIHwgMFxuICAgIGUgPSAoZCArIHQxICsgKChlbCA+Pj4gMCkgPCAoZGwgPj4+IDApID8gMSA6IDApKSB8IDBcbiAgICBkID0gY1xuICAgIGRsID0gY2xcbiAgICBjID0gYlxuICAgIGNsID0gYmxcbiAgICBiID0gYVxuICAgIGJsID0gYWxcbiAgICBhbCA9ICh0MWwgKyB0MmwpIHwgMFxuICAgIGEgPSAodDEgKyB0MiArICgoYWwgPj4+IDApIDwgKHQxbCA+Pj4gMCkgPyAxIDogMCkpIHwgMFxuXG4gICAgaSsrXG4gICAgaiArPSAyXG4gIH1cblxuICB3aGlsZSAoaSA8IDE2KSB7XG4gICAgV2kgPSBNLnJlYWRJbnQzMkJFKGogKiA0KVxuICAgIFdpbCA9IE0ucmVhZEludDMyQkUoaiAqIDQgKyA0KVxuXG4gICAgbG9vcCgpXG4gIH1cblxuICB3aGlsZSAoaSA8IDgwKSB7XG4gICAgY2FsY1coKVxuICAgIGxvb3AoKVxuICB9XG5cbiAgdGhpcy5fYWwgPSAodGhpcy5fYWwgKyBhbCkgfCAwXG4gIHRoaXMuX2JsID0gKHRoaXMuX2JsICsgYmwpIHwgMFxuICB0aGlzLl9jbCA9ICh0aGlzLl9jbCArIGNsKSB8IDBcbiAgdGhpcy5fZGwgPSAodGhpcy5fZGwgKyBkbCkgfCAwXG4gIHRoaXMuX2VsID0gKHRoaXMuX2VsICsgZWwpIHwgMFxuICB0aGlzLl9mbCA9ICh0aGlzLl9mbCArIGZsKSB8IDBcbiAgdGhpcy5fZ2wgPSAodGhpcy5fZ2wgKyBnbCkgfCAwXG4gIHRoaXMuX2hsID0gKHRoaXMuX2hsICsgaGwpIHwgMFxuXG4gIHRoaXMuX2EgPSAodGhpcy5fYSArIGEgKyAoKHRoaXMuX2FsID4+PiAwKSA8IChhbCA+Pj4gMCkgPyAxIDogMCkpIHwgMFxuICB0aGlzLl9iID0gKHRoaXMuX2IgKyBiICsgKCh0aGlzLl9ibCA+Pj4gMCkgPCAoYmwgPj4+IDApID8gMSA6IDApKSB8IDBcbiAgdGhpcy5fYyA9ICh0aGlzLl9jICsgYyArICgodGhpcy5fY2wgPj4+IDApIDwgKGNsID4+PiAwKSA/IDEgOiAwKSkgfCAwXG4gIHRoaXMuX2QgPSAodGhpcy5fZCArIGQgKyAoKHRoaXMuX2RsID4+PiAwKSA8IChkbCA+Pj4gMCkgPyAxIDogMCkpIHwgMFxuICB0aGlzLl9lID0gKHRoaXMuX2UgKyBlICsgKCh0aGlzLl9lbCA+Pj4gMCkgPCAoZWwgPj4+IDApID8gMSA6IDApKSB8IDBcbiAgdGhpcy5fZiA9ICh0aGlzLl9mICsgZiArICgodGhpcy5fZmwgPj4+IDApIDwgKGZsID4+PiAwKSA/IDEgOiAwKSkgfCAwXG4gIHRoaXMuX2cgPSAodGhpcy5fZyArIGcgKyAoKHRoaXMuX2dsID4+PiAwKSA8IChnbCA+Pj4gMCkgPyAxIDogMCkpIHwgMFxuICB0aGlzLl9oID0gKHRoaXMuX2ggKyBoICsgKCh0aGlzLl9obCA+Pj4gMCkgPCAoaGwgPj4+IDApID8gMSA6IDApKSB8IDBcbn1cblxuU2hhNTEyLnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBuZXcgQnVmZmVyKDY0KVxuXG4gIGZ1bmN0aW9uIHdyaXRlSW50NjRCRSAoaCwgbCwgb2Zmc2V0KSB7XG4gICAgSC53cml0ZUludDMyQkUoaCwgb2Zmc2V0KVxuICAgIEgud3JpdGVJbnQzMkJFKGwsIG9mZnNldCArIDQpXG4gIH1cblxuICB3cml0ZUludDY0QkUodGhpcy5fYSwgdGhpcy5fYWwsIDApXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9iLCB0aGlzLl9ibCwgOClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2MsIHRoaXMuX2NsLCAxNilcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2QsIHRoaXMuX2RsLCAyNClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2UsIHRoaXMuX2VsLCAzMilcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2YsIHRoaXMuX2ZsLCA0MClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2csIHRoaXMuX2dsLCA0OClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2gsIHRoaXMuX2hsLCA1NilcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYTUxMlxuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGNyZWF0ZUhhc2ggPSByZXF1aXJlKCdjcmVhdGUtaGFzaC9icm93c2VyJyk7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG5cbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdzdHJlYW0nKS5UcmFuc2Zvcm1cblxudmFyIFpFUk9TID0gbmV3IEJ1ZmZlcigxMjgpXG5aRVJPUy5maWxsKDApXG5cbmZ1bmN0aW9uIEhtYWMoYWxnLCBrZXkpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgYWxnID0gYWxnLnRvTG93ZXJDYXNlKClcbiAgaWYgKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnKSB7XG4gICAga2V5ID0gbmV3IEJ1ZmZlcihrZXkpXG4gIH1cblxuICB2YXIgYmxvY2tzaXplID0gKGFsZyA9PT0gJ3NoYTUxMicgfHwgYWxnID09PSAnc2hhMzg0JykgPyAxMjggOiA2NFxuXG4gIHRoaXMuX2FsZyA9IGFsZ1xuICB0aGlzLl9rZXkgPSBrZXlcblxuICBpZiAoa2V5Lmxlbmd0aCA+IGJsb2Nrc2l6ZSkge1xuICAgIGtleSA9IGNyZWF0ZUhhc2goYWxnKS51cGRhdGUoa2V5KS5kaWdlc3QoKVxuXG4gIH0gZWxzZSBpZiAoa2V5Lmxlbmd0aCA8IGJsb2Nrc2l6ZSkge1xuICAgIGtleSA9IEJ1ZmZlci5jb25jYXQoW2tleSwgWkVST1NdLCBibG9ja3NpemUpXG4gIH1cblxuICB2YXIgaXBhZCA9IHRoaXMuX2lwYWQgPSBuZXcgQnVmZmVyKGJsb2Nrc2l6ZSlcbiAgdmFyIG9wYWQgPSB0aGlzLl9vcGFkID0gbmV3IEJ1ZmZlcihibG9ja3NpemUpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja3NpemU7IGkrKykge1xuICAgIGlwYWRbaV0gPSBrZXlbaV0gXiAweDM2XG4gICAgb3BhZFtpXSA9IGtleVtpXSBeIDB4NUNcbiAgfVxuXG4gIHRoaXMuX2hhc2ggPSBjcmVhdGVIYXNoKGFsZykudXBkYXRlKGlwYWQpXG59XG5cbmluaGVyaXRzKEhtYWMsIFRyYW5zZm9ybSlcblxuSG1hYy5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGVuYykge1xuICB0aGlzLl9oYXNoLnVwZGF0ZShkYXRhLCBlbmMpXG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuSG1hYy5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChkYXRhLCBfLCBuZXh0KSB7XG4gIHRoaXMuX2hhc2gudXBkYXRlKGRhdGEpXG5cbiAgbmV4dCgpXG59XG5cbkhtYWMucHJvdG90eXBlLl9mbHVzaCA9IGZ1bmN0aW9uIChuZXh0KSB7XG4gIHRoaXMucHVzaCh0aGlzLmRpZ2VzdCgpKVxuXG4gIG5leHQoKVxufVxuXG5IbWFjLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiAoZW5jKSB7XG4gIHZhciBoID0gdGhpcy5faGFzaC5kaWdlc3QoKVxuXG4gIHJldHVybiBjcmVhdGVIYXNoKHRoaXMuX2FsZykudXBkYXRlKHRoaXMuX29wYWQpLnVwZGF0ZShoKS5kaWdlc3QoZW5jKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNyZWF0ZUhtYWMoYWxnLCBrZXkpIHtcbiAgcmV0dXJuIG5ldyBIbWFjKGFsZywga2V5KVxufVxuIiwidmFyIGdlbmVyYXRlUHJpbWUgPSByZXF1aXJlKCcuL2xpYi9nZW5lcmF0ZVByaW1lJylcbnZhciBwcmltZXMgPSByZXF1aXJlKCcuL2xpYi9wcmltZXMuanNvbicpXG5cbnZhciBESCA9IHJlcXVpcmUoJy4vbGliL2RoJylcblxuZnVuY3Rpb24gZ2V0RGlmZmllSGVsbG1hbiAobW9kKSB7XG4gIHZhciBwcmltZSA9IG5ldyBCdWZmZXIocHJpbWVzW21vZF0ucHJpbWUsICdoZXgnKVxuICB2YXIgZ2VuID0gbmV3IEJ1ZmZlcihwcmltZXNbbW9kXS5nZW4sICdoZXgnKVxuXG4gIHJldHVybiBuZXcgREgocHJpbWUsIGdlbilcbn1cblxudmFyIEVOQ09ESU5HUyA9IHtcbiAgJ2JpbmFyeSc6IHRydWUsICdoZXgnOiB0cnVlLCAnYmFzZTY0JzogdHJ1ZVxufVxuXG5mdW5jdGlvbiBjcmVhdGVEaWZmaWVIZWxsbWFuIChwcmltZSwgZW5jLCBnZW5lcmF0b3IsIGdlbmMpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihlbmMpIHx8IEVOQ09ESU5HU1tlbmNdID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gY3JlYXRlRGlmZmllSGVsbG1hbihwcmltZSwgJ2JpbmFyeScsIGVuYywgZ2VuZXJhdG9yKVxuICB9XG5cbiAgZW5jID0gZW5jIHx8ICdiaW5hcnknXG4gIGdlbmMgPSBnZW5jIHx8ICdiaW5hcnknXG4gIGdlbmVyYXRvciA9IGdlbmVyYXRvciB8fCBuZXcgQnVmZmVyKFsyXSlcblxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihnZW5lcmF0b3IpKSB7XG4gICAgZ2VuZXJhdG9yID0gbmV3IEJ1ZmZlcihnZW5lcmF0b3IsIGdlbmMpXG4gIH1cblxuICBpZiAodHlwZW9mIHByaW1lID09PSAnbnVtYmVyJykge1xuICAgIHJldHVybiBuZXcgREgoZ2VuZXJhdGVQcmltZShwcmltZSwgZ2VuZXJhdG9yKSwgZ2VuZXJhdG9yLCB0cnVlKVxuICB9XG5cbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIocHJpbWUpKSB7XG4gICAgcHJpbWUgPSBuZXcgQnVmZmVyKHByaW1lLCBlbmMpXG4gIH1cblxuICByZXR1cm4gbmV3IERIKHByaW1lLCBnZW5lcmF0b3IsIHRydWUpXG59XG5cbmV4cG9ydHMuRGlmZmllSGVsbG1hbkdyb3VwID0gZXhwb3J0cy5jcmVhdGVEaWZmaWVIZWxsbWFuR3JvdXAgPSBleHBvcnRzLmdldERpZmZpZUhlbGxtYW4gPSBnZXREaWZmaWVIZWxsbWFuXG5leHBvcnRzLmNyZWF0ZURpZmZpZUhlbGxtYW4gPSBleHBvcnRzLkRpZmZpZUhlbGxtYW4gPSBjcmVhdGVEaWZmaWVIZWxsbWFuXG4iLCJ2YXIgQk4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIE1pbGxlclJhYmluID0gcmVxdWlyZSgnbWlsbGVyLXJhYmluJyk7XG52YXIgbWlsbGVyUmFiaW4gPSBuZXcgTWlsbGVyUmFiaW4oKTtcbnZhciBUV0VOVFlGT1VSID0gbmV3IEJOKDI0KTtcbnZhciBFTEVWRU4gPSBuZXcgQk4oMTEpO1xudmFyIFRFTiA9IG5ldyBCTigxMCk7XG52YXIgVEhSRUUgPSBuZXcgQk4oMyk7XG52YXIgU0VWRU4gPSBuZXcgQk4oNyk7XG52YXIgcHJpbWVzID0gcmVxdWlyZSgnLi9nZW5lcmF0ZVByaW1lJyk7XG52YXIgcmFuZG9tQnl0ZXMgPSByZXF1aXJlKCdyYW5kb21ieXRlcycpO1xubW9kdWxlLmV4cG9ydHMgPSBESDtcblxuZnVuY3Rpb24gc2V0UHVibGljS2V5KHB1YiwgZW5jKSB7XG4gIGVuYyA9IGVuYyB8fCAndXRmOCc7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHB1YikpIHtcbiAgICBwdWIgPSBuZXcgQnVmZmVyKHB1YiwgZW5jKTtcbiAgfVxuICB0aGlzLl9wdWIgPSBuZXcgQk4ocHViKTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbmZ1bmN0aW9uIHNldFByaXZhdGVLZXkocHJpdiwgZW5jKSB7XG4gIGVuYyA9IGVuYyB8fCAndXRmOCc7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHByaXYpKSB7XG4gICAgcHJpdiA9IG5ldyBCdWZmZXIocHJpdiwgZW5jKTtcbiAgfVxuICB0aGlzLl9wcml2ID0gbmV3IEJOKHByaXYpO1xuICByZXR1cm4gdGhpcztcbn1cblxudmFyIHByaW1lQ2FjaGUgPSB7fTtcbmZ1bmN0aW9uIGNoZWNrUHJpbWUocHJpbWUsIGdlbmVyYXRvcikge1xuICB2YXIgZ2VuID0gZ2VuZXJhdG9yLnRvU3RyaW5nKCdoZXgnKTtcbiAgdmFyIGhleCA9IFtnZW4sIHByaW1lLnRvU3RyaW5nKDE2KV0uam9pbignXycpO1xuICBpZiAoaGV4IGluIHByaW1lQ2FjaGUpIHtcbiAgICByZXR1cm4gcHJpbWVDYWNoZVtoZXhdO1xuICB9XG4gIHZhciBlcnJvciA9IDA7XG5cbiAgaWYgKHByaW1lLmlzRXZlbigpIHx8XG4gICAgIXByaW1lcy5zaW1wbGVTaWV2ZSB8fFxuICAgICFwcmltZXMuZmVybWF0VGVzdChwcmltZSkgfHxcbiAgICAhbWlsbGVyUmFiaW4udGVzdChwcmltZSkpIHtcbiAgICAvL25vdCBhIHByaW1lIHNvICsxXG4gICAgZXJyb3IgKz0gMTtcblxuICAgIGlmIChnZW4gPT09ICcwMicgfHwgZ2VuID09PSAnMDUnKSB7XG4gICAgICAvLyB3ZSdkIGJlIGFibGUgdG8gY2hlY2sgdGhlIGdlbmVyYXRvclxuICAgICAgLy8gaXQgd291bGQgZmFpbCBzbyArOFxuICAgICAgZXJyb3IgKz0gODtcbiAgICB9IGVsc2Uge1xuICAgICAgLy93ZSB3b3VsZG4ndCBiZSBhYmxlIHRvIHRlc3QgdGhlIGdlbmVyYXRvclxuICAgICAgLy8gc28gKzRcbiAgICAgIGVycm9yICs9IDQ7XG4gICAgfVxuICAgIHByaW1lQ2FjaGVbaGV4XSA9IGVycm9yO1xuICAgIHJldHVybiBlcnJvcjtcbiAgfVxuICBpZiAoIW1pbGxlclJhYmluLnRlc3QocHJpbWUuc2hybigxKSkpIHtcbiAgICAvL25vdCBhIHNhZmUgcHJpbWVcbiAgICBlcnJvciArPSAyO1xuICB9XG4gIHZhciByZW07XG4gIHN3aXRjaCAoZ2VuKSB7XG4gICAgY2FzZSAnMDInOlxuICAgICAgaWYgKHByaW1lLm1vZChUV0VOVFlGT1VSKS5jbXAoRUxFVkVOKSkge1xuICAgICAgICAvLyB1bnN1aWRhYmxlIGdlbmVyYXRvclxuICAgICAgICBlcnJvciArPSA4O1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnMDUnOlxuICAgICAgcmVtID0gcHJpbWUubW9kKFRFTik7XG4gICAgICBpZiAocmVtLmNtcChUSFJFRSkgJiYgcmVtLmNtcChTRVZFTikpIHtcbiAgICAgICAgLy8gcHJpbWUgbW9kIDEwIG5lZWRzIHRvIGVxdWFsIDMgb3IgN1xuICAgICAgICBlcnJvciArPSA4O1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIGVycm9yICs9IDQ7XG4gIH1cbiAgcHJpbWVDYWNoZVtoZXhdID0gZXJyb3I7XG4gIHJldHVybiBlcnJvcjtcbn1cblxuZnVuY3Rpb24gREgocHJpbWUsIGdlbmVyYXRvciwgbWFsbGVhYmxlKSB7XG4gIHRoaXMuc2V0R2VuZXJhdG9yKGdlbmVyYXRvcik7XG4gIHRoaXMuX19wcmltZSA9IG5ldyBCTihwcmltZSk7XG4gIHRoaXMuX3ByaW1lID0gQk4ubW9udCh0aGlzLl9fcHJpbWUpO1xuICB0aGlzLl9wcmltZUxlbiA9IHByaW1lLmxlbmd0aDtcbiAgdGhpcy5fcHViID0gdW5kZWZpbmVkO1xuICB0aGlzLl9wcml2ID0gdW5kZWZpbmVkO1xuICB0aGlzLl9wcmltZUNvZGUgPSB1bmRlZmluZWQ7XG4gIGlmIChtYWxsZWFibGUpIHtcbiAgICB0aGlzLnNldFB1YmxpY0tleSA9IHNldFB1YmxpY0tleTtcbiAgICB0aGlzLnNldFByaXZhdGVLZXkgPSBzZXRQcml2YXRlS2V5O1xuICB9IGVsc2Uge1xuICAgIHRoaXMuX3ByaW1lQ29kZSA9IDg7XG4gIH1cbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShESC5wcm90b3R5cGUsICd2ZXJpZnlFcnJvcicsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLl9wcmltZUNvZGUgIT09ICdudW1iZXInKSB7XG4gICAgICB0aGlzLl9wcmltZUNvZGUgPSBjaGVja1ByaW1lKHRoaXMuX19wcmltZSwgdGhpcy5fX2dlbik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9wcmltZUNvZGU7XG4gIH1cbn0pO1xuREgucHJvdG90eXBlLmdlbmVyYXRlS2V5cyA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLl9wcml2KSB7XG4gICAgdGhpcy5fcHJpdiA9IG5ldyBCTihyYW5kb21CeXRlcyh0aGlzLl9wcmltZUxlbikpO1xuICB9XG4gIHRoaXMuX3B1YiA9IHRoaXMuX2dlbi50b1JlZCh0aGlzLl9wcmltZSkucmVkUG93KHRoaXMuX3ByaXYpLmZyb21SZWQoKTtcbiAgcmV0dXJuIHRoaXMuZ2V0UHVibGljS2V5KCk7XG59O1xuXG5ESC5wcm90b3R5cGUuY29tcHV0ZVNlY3JldCA9IGZ1bmN0aW9uIChvdGhlcikge1xuICBvdGhlciA9IG5ldyBCTihvdGhlcik7XG4gIG90aGVyID0gb3RoZXIudG9SZWQodGhpcy5fcHJpbWUpO1xuICB2YXIgc2VjcmV0ID0gb3RoZXIucmVkUG93KHRoaXMuX3ByaXYpLmZyb21SZWQoKTtcbiAgdmFyIG91dCA9IG5ldyBCdWZmZXIoc2VjcmV0LnRvQXJyYXkoKSk7XG4gIHZhciBwcmltZSA9IHRoaXMuZ2V0UHJpbWUoKTtcbiAgaWYgKG91dC5sZW5ndGggPCBwcmltZS5sZW5ndGgpIHtcbiAgICB2YXIgZnJvbnQgPSBuZXcgQnVmZmVyKHByaW1lLmxlbmd0aCAtIG91dC5sZW5ndGgpO1xuICAgIGZyb250LmZpbGwoMCk7XG4gICAgb3V0ID0gQnVmZmVyLmNvbmNhdChbZnJvbnQsIG91dF0pO1xuICB9XG4gIHJldHVybiBvdXQ7XG59O1xuXG5ESC5wcm90b3R5cGUuZ2V0UHVibGljS2V5ID0gZnVuY3Rpb24gZ2V0UHVibGljS2V5KGVuYykge1xuICByZXR1cm4gZm9ybWF0UmV0dXJuVmFsdWUodGhpcy5fcHViLCBlbmMpO1xufTtcblxuREgucHJvdG90eXBlLmdldFByaXZhdGVLZXkgPSBmdW5jdGlvbiBnZXRQcml2YXRlS2V5KGVuYykge1xuICByZXR1cm4gZm9ybWF0UmV0dXJuVmFsdWUodGhpcy5fcHJpdiwgZW5jKTtcbn07XG5cbkRILnByb3RvdHlwZS5nZXRQcmltZSA9IGZ1bmN0aW9uIChlbmMpIHtcbiAgcmV0dXJuIGZvcm1hdFJldHVyblZhbHVlKHRoaXMuX19wcmltZSwgZW5jKTtcbn07XG5cbkRILnByb3RvdHlwZS5nZXRHZW5lcmF0b3IgPSBmdW5jdGlvbiAoZW5jKSB7XG4gIHJldHVybiBmb3JtYXRSZXR1cm5WYWx1ZSh0aGlzLl9nZW4sIGVuYyk7XG59O1xuXG5ESC5wcm90b3R5cGUuc2V0R2VuZXJhdG9yID0gZnVuY3Rpb24gKGdlbiwgZW5jKSB7XG4gIGVuYyA9IGVuYyB8fCAndXRmOCc7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGdlbikpIHtcbiAgICBnZW4gPSBuZXcgQnVmZmVyKGdlbiwgZW5jKTtcbiAgfVxuICB0aGlzLl9fZ2VuID0gZ2VuO1xuICB0aGlzLl9nZW4gPSBuZXcgQk4oZ2VuKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBmb3JtYXRSZXR1cm5WYWx1ZShibiwgZW5jKSB7XG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKGJuLnRvQXJyYXkoKSk7XG4gIGlmICghZW5jKSB7XG4gICAgcmV0dXJuIGJ1ZjtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYnVmLnRvU3RyaW5nKGVuYyk7XG4gIH1cbn1cbiIsInZhciByYW5kb21CeXRlcyA9IHJlcXVpcmUoJ3JhbmRvbWJ5dGVzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZpbmRQcmltZTtcbmZpbmRQcmltZS5zaW1wbGVTaWV2ZSA9IHNpbXBsZVNpZXZlO1xuZmluZFByaW1lLmZlcm1hdFRlc3QgPSBmZXJtYXRUZXN0O1xudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciBUV0VOVFlGT1VSID0gbmV3IEJOKDI0KTtcbnZhciBNaWxsZXJSYWJpbiA9IHJlcXVpcmUoJ21pbGxlci1yYWJpbicpO1xudmFyIG1pbGxlclJhYmluID0gbmV3IE1pbGxlclJhYmluKCk7XG52YXIgT05FID0gbmV3IEJOKDEpO1xudmFyIFRXTyA9IG5ldyBCTigyKTtcbnZhciBGSVZFID0gbmV3IEJOKDUpO1xudmFyIFNJWFRFRU4gPSBuZXcgQk4oMTYpO1xudmFyIEVJR0hUID0gbmV3IEJOKDgpO1xudmFyIFRFTiA9IG5ldyBCTigxMCk7XG52YXIgVEhSRUUgPSBuZXcgQk4oMyk7XG52YXIgU0VWRU4gPSBuZXcgQk4oNyk7XG52YXIgRUxFVkVOID0gbmV3IEJOKDExKTtcbnZhciBGT1VSID0gbmV3IEJOKDQpO1xudmFyIFRXRUxWRSA9IG5ldyBCTigxMik7XG52YXIgcHJpbWVzID0gbnVsbDtcblxuZnVuY3Rpb24gX2dldFByaW1lcygpIHtcbiAgaWYgKHByaW1lcyAhPT0gbnVsbClcbiAgICByZXR1cm4gcHJpbWVzO1xuXG4gIHZhciBsaW1pdCA9IDB4MTAwMDAwO1xuICB2YXIgcmVzID0gW107XG4gIHJlc1swXSA9IDI7XG4gIGZvciAodmFyIGkgPSAxLCBrID0gMzsgayA8IGxpbWl0OyBrICs9IDIpIHtcbiAgICB2YXIgc3FydCA9IE1hdGguY2VpbChNYXRoLnNxcnQoaykpO1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgaSAmJiByZXNbal0gPD0gc3FydDsgaisrKVxuICAgICAgaWYgKGsgJSByZXNbal0gPT09IDApXG4gICAgICAgIGJyZWFrO1xuXG4gICAgaWYgKGkgIT09IGogJiYgcmVzW2pdIDw9IHNxcnQpXG4gICAgICBjb250aW51ZTtcblxuICAgIHJlc1tpKytdID0gaztcbiAgfVxuICBwcmltZXMgPSByZXM7XG4gIHJldHVybiByZXM7XG59XG5cbmZ1bmN0aW9uIHNpbXBsZVNpZXZlKHApIHtcbiAgdmFyIHByaW1lcyA9IF9nZXRQcmltZXMoKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHByaW1lcy5sZW5ndGg7IGkrKylcbiAgICBpZiAocC5tb2RuKHByaW1lc1tpXSkgPT09IDApIHtcbiAgICAgIGlmIChwLmNtcG4ocHJpbWVzW2ldKSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGZlcm1hdFRlc3QocCkge1xuICB2YXIgcmVkID0gQk4ubW9udChwKTtcbiAgcmV0dXJuIFRXTy50b1JlZChyZWQpLnJlZFBvdyhwLnN1Ym4oMSkpLmZyb21SZWQoKS5jbXBuKDEpID09PSAwO1xufVxuXG5mdW5jdGlvbiBmaW5kUHJpbWUoYml0cywgZ2VuKSB7XG4gIGlmIChiaXRzIDwgMTYpIHtcbiAgICAvLyB0aGlzIGlzIHdoYXQgb3BlbnNzbCBkb2VzXG4gICAgaWYgKGdlbiA9PT0gMiB8fCBnZW4gPT09IDUpIHtcbiAgICAgIHJldHVybiBuZXcgQk4oWzB4OGMsIDB4N2JdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG5ldyBCTihbMHg4YywgMHgyN10pO1xuICAgIH1cbiAgfVxuICBnZW4gPSBuZXcgQk4oZ2VuKTtcblxuICB2YXIgbnVtLCBuMjtcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIG51bSA9IG5ldyBCTihyYW5kb21CeXRlcyhNYXRoLmNlaWwoYml0cyAvIDgpKSk7XG4gICAgd2hpbGUgKG51bS5iaXRMZW5ndGgoKSA+IGJpdHMpIHtcbiAgICAgIG51bS5pc2hybigxKTtcbiAgICB9XG4gICAgaWYgKG51bS5pc0V2ZW4oKSkge1xuICAgICAgbnVtLmlhZGQoT05FKTtcbiAgICB9XG4gICAgaWYgKCFudW0udGVzdG4oMSkpIHtcbiAgICAgIG51bS5pYWRkKFRXTyk7XG4gICAgfVxuICAgIGlmICghZ2VuLmNtcChUV08pKSB7XG4gICAgICB3aGlsZSAobnVtLm1vZChUV0VOVFlGT1VSKS5jbXAoRUxFVkVOKSkge1xuICAgICAgICBudW0uaWFkZChGT1VSKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCFnZW4uY21wKEZJVkUpKSB7XG4gICAgICB3aGlsZSAobnVtLm1vZChURU4pLmNtcChUSFJFRSkpIHtcbiAgICAgICAgbnVtLmlhZGQoRk9VUik7XG4gICAgICB9XG4gICAgfVxuICAgIG4yID0gbnVtLnNocm4oMSk7XG4gICAgaWYgKHNpbXBsZVNpZXZlKG4yKSAmJiBzaW1wbGVTaWV2ZShudW0pICYmXG4gICAgICBmZXJtYXRUZXN0KG4yKSAmJiBmZXJtYXRUZXN0KG51bSkgJiZcbiAgICAgIG1pbGxlclJhYmluLnRlc3QobjIpICYmIG1pbGxlclJhYmluLnRlc3QobnVtKSkge1xuICAgICAgcmV0dXJuIG51bTtcbiAgICB9XG4gIH1cblxufVxuIiwibW9kdWxlLmV4cG9ydHM9e1xuICAgIFwibW9kcDFcIjoge1xuICAgICAgICBcImdlblwiOiBcIjAyXCIsXG4gICAgICAgIFwicHJpbWVcIjogXCJmZmZmZmZmZmZmZmZmZmZmYzkwZmRhYTIyMTY4YzIzNGM0YzY2MjhiODBkYzFjZDEyOTAyNGUwODhhNjdjYzc0MDIwYmJlYTYzYjEzOWIyMjUxNGEwODc5OGUzNDA0ZGRlZjk1MTliM2NkM2E0MzFiMzAyYjBhNmRmMjVmMTQzNzRmZTEzNTZkNmQ1MWMyNDVlNDg1YjU3NjYyNWU3ZWM2ZjQ0YzQyZTlhNjNhMzYyMGZmZmZmZmZmZmZmZmZmZmZcIlxuICAgIH0sXG4gICAgXCJtb2RwMlwiOiB7XG4gICAgICAgIFwiZ2VuXCI6IFwiMDJcIixcbiAgICAgICAgXCJwcmltZVwiOiBcImZmZmZmZmZmZmZmZmZmZmZjOTBmZGFhMjIxNjhjMjM0YzRjNjYyOGI4MGRjMWNkMTI5MDI0ZTA4OGE2N2NjNzQwMjBiYmVhNjNiMTM5YjIyNTE0YTA4Nzk4ZTM0MDRkZGVmOTUxOWIzY2QzYTQzMWIzMDJiMGE2ZGYyNWYxNDM3NGZlMTM1NmQ2ZDUxYzI0NWU0ODViNTc2NjI1ZTdlYzZmNDRjNDJlOWE2MzdlZDZiMGJmZjVjYjZmNDA2YjdlZGVlMzg2YmZiNWE4OTlmYTVhZTlmMjQxMTdjNGIxZmU2NDkyODY2NTFlY2U2NTM4MWZmZmZmZmZmZmZmZmZmZmZcIlxuICAgIH0sXG4gICAgXCJtb2RwNVwiOiB7XG4gICAgICAgIFwiZ2VuXCI6IFwiMDJcIixcbiAgICAgICAgXCJwcmltZVwiOiBcImZmZmZmZmZmZmZmZmZmZmZjOTBmZGFhMjIxNjhjMjM0YzRjNjYyOGI4MGRjMWNkMTI5MDI0ZTA4OGE2N2NjNzQwMjBiYmVhNjNiMTM5YjIyNTE0YTA4Nzk4ZTM0MDRkZGVmOTUxOWIzY2QzYTQzMWIzMDJiMGE2ZGYyNWYxNDM3NGZlMTM1NmQ2ZDUxYzI0NWU0ODViNTc2NjI1ZTdlYzZmNDRjNDJlOWE2MzdlZDZiMGJmZjVjYjZmNDA2YjdlZGVlMzg2YmZiNWE4OTlmYTVhZTlmMjQxMTdjNGIxZmU2NDkyODY2NTFlY2U0NWIzZGMyMDA3Y2I4YTE2M2JmMDU5OGRhNDgzNjFjNTVkMzlhNjkxNjNmYThmZDI0Y2Y1ZjgzNjU1ZDIzZGNhM2FkOTYxYzYyZjM1NjIwODU1MmJiOWVkNTI5MDc3MDk2OTY2ZDY3MGMzNTRlNGFiYzk4MDRmMTc0NmMwOGNhMjM3MzI3ZmZmZmZmZmZmZmZmZmZmZlwiXG4gICAgfSxcbiAgICBcIm1vZHAxNFwiOiB7XG4gICAgICAgIFwiZ2VuXCI6IFwiMDJcIixcbiAgICAgICAgXCJwcmltZVwiOiBcImZmZmZmZmZmZmZmZmZmZmZjOTBmZGFhMjIxNjhjMjM0YzRjNjYyOGI4MGRjMWNkMTI5MDI0ZTA4OGE2N2NjNzQwMjBiYmVhNjNiMTM5YjIyNTE0YTA4Nzk4ZTM0MDRkZGVmOTUxOWIzY2QzYTQzMWIzMDJiMGE2ZGYyNWYxNDM3NGZlMTM1NmQ2ZDUxYzI0NWU0ODViNTc2NjI1ZTdlYzZmNDRjNDJlOWE2MzdlZDZiMGJmZjVjYjZmNDA2YjdlZGVlMzg2YmZiNWE4OTlmYTVhZTlmMjQxMTdjNGIxZmU2NDkyODY2NTFlY2U0NWIzZGMyMDA3Y2I4YTE2M2JmMDU5OGRhNDgzNjFjNTVkMzlhNjkxNjNmYThmZDI0Y2Y1ZjgzNjU1ZDIzZGNhM2FkOTYxYzYyZjM1NjIwODU1MmJiOWVkNTI5MDc3MDk2OTY2ZDY3MGMzNTRlNGFiYzk4MDRmMTc0NmMwOGNhMTgyMTdjMzI5MDVlNDYyZTM2Y2UzYmUzOWU3NzJjMTgwZTg2MDM5YjI3ODNhMmVjMDdhMjhmYjVjNTVkZjA2ZjRjNTJjOWRlMmJjYmY2OTU1ODE3MTgzOTk1NDk3Y2VhOTU2YWU1MTVkMjI2MTg5OGZhMDUxMDE1NzI4ZTVhOGFhY2FhNjhmZmZmZmZmZmZmZmZmZmZmXCJcbiAgICB9LFxuICAgIFwibW9kcDE1XCI6IHtcbiAgICAgICAgXCJnZW5cIjogXCIwMlwiLFxuICAgICAgICBcInByaW1lXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmM5MGZkYWEyMjE2OGMyMzRjNGM2NjI4YjgwZGMxY2QxMjkwMjRlMDg4YTY3Y2M3NDAyMGJiZWE2M2IxMzliMjI1MTRhMDg3OThlMzQwNGRkZWY5NTE5YjNjZDNhNDMxYjMwMmIwYTZkZjI1ZjE0Mzc0ZmUxMzU2ZDZkNTFjMjQ1ZTQ4NWI1NzY2MjVlN2VjNmY0NGM0MmU5YTYzN2VkNmIwYmZmNWNiNmY0MDZiN2VkZWUzODZiZmI1YTg5OWZhNWFlOWYyNDExN2M0YjFmZTY0OTI4NjY1MWVjZTQ1YjNkYzIwMDdjYjhhMTYzYmYwNTk4ZGE0ODM2MWM1NWQzOWE2OTE2M2ZhOGZkMjRjZjVmODM2NTVkMjNkY2EzYWQ5NjFjNjJmMzU2MjA4NTUyYmI5ZWQ1MjkwNzcwOTY5NjZkNjcwYzM1NGU0YWJjOTgwNGYxNzQ2YzA4Y2ExODIxN2MzMjkwNWU0NjJlMzZjZTNiZTM5ZTc3MmMxODBlODYwMzliMjc4M2EyZWMwN2EyOGZiNWM1NWRmMDZmNGM1MmM5ZGUyYmNiZjY5NTU4MTcxODM5OTU0OTdjZWE5NTZhZTUxNWQyMjYxODk4ZmEwNTEwMTU3MjhlNWE4YWFhYzQyZGFkMzMxNzBkMDQ1MDdhMzNhODU1MjFhYmRmMWNiYTY0ZWNmYjg1MDQ1OGRiZWYwYThhZWE3MTU3NWQwNjBjN2RiMzk3MGY4NWE2ZTFlNGM3YWJmNWFlOGNkYjA5MzNkNzFlOGM5NGUwNGEyNTYxOWRjZWUzZDIyNjFhZDJlZTZiZjEyZmZhMDZkOThhMDg2NGQ4NzYwMjczM2VjODZhNjQ1MjFmMmIxODE3N2IyMDBjYmJlMTE3NTc3YTYxNWQ2Yzc3MDk4OGMwYmFkOTQ2ZTIwOGUyNGZhMDc0ZTVhYjMxNDNkYjViZmNlMGZkMTA4ZTRiODJkMTIwYTkzYWQyY2FmZmZmZmZmZmZmZmZmZmZmXCJcbiAgICB9LFxuICAgIFwibW9kcDE2XCI6IHtcbiAgICAgICAgXCJnZW5cIjogXCIwMlwiLFxuICAgICAgICBcInByaW1lXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmM5MGZkYWEyMjE2OGMyMzRjNGM2NjI4YjgwZGMxY2QxMjkwMjRlMDg4YTY3Y2M3NDAyMGJiZWE2M2IxMzliMjI1MTRhMDg3OThlMzQwNGRkZWY5NTE5YjNjZDNhNDMxYjMwMmIwYTZkZjI1ZjE0Mzc0ZmUxMzU2ZDZkNTFjMjQ1ZTQ4NWI1NzY2MjVlN2VjNmY0NGM0MmU5YTYzN2VkNmIwYmZmNWNiNmY0MDZiN2VkZWUzODZiZmI1YTg5OWZhNWFlOWYyNDExN2M0YjFmZTY0OTI4NjY1MWVjZTQ1YjNkYzIwMDdjYjhhMTYzYmYwNTk4ZGE0ODM2MWM1NWQzOWE2OTE2M2ZhOGZkMjRjZjVmODM2NTVkMjNkY2EzYWQ5NjFjNjJmMzU2MjA4NTUyYmI5ZWQ1MjkwNzcwOTY5NjZkNjcwYzM1NGU0YWJjOTgwNGYxNzQ2YzA4Y2ExODIxN2MzMjkwNWU0NjJlMzZjZTNiZTM5ZTc3MmMxODBlODYwMzliMjc4M2EyZWMwN2EyOGZiNWM1NWRmMDZmNGM1MmM5ZGUyYmNiZjY5NTU4MTcxODM5OTU0OTdjZWE5NTZhZTUxNWQyMjYxODk4ZmEwNTEwMTU3MjhlNWE4YWFhYzQyZGFkMzMxNzBkMDQ1MDdhMzNhODU1MjFhYmRmMWNiYTY0ZWNmYjg1MDQ1OGRiZWYwYThhZWE3MTU3NWQwNjBjN2RiMzk3MGY4NWE2ZTFlNGM3YWJmNWFlOGNkYjA5MzNkNzFlOGM5NGUwNGEyNTYxOWRjZWUzZDIyNjFhZDJlZTZiZjEyZmZhMDZkOThhMDg2NGQ4NzYwMjczM2VjODZhNjQ1MjFmMmIxODE3N2IyMDBjYmJlMTE3NTc3YTYxNWQ2Yzc3MDk4OGMwYmFkOTQ2ZTIwOGUyNGZhMDc0ZTVhYjMxNDNkYjViZmNlMGZkMTA4ZTRiODJkMTIwYTkyMTA4MDExYTcyM2MxMmE3ODdlNmQ3ODg3MTlhMTBiZGJhNWIyNjk5YzMyNzE4NmFmNGUyM2MxYTk0NjgzNGI2MTUwYmRhMjU4M2U5Y2EyYWQ0NGNlOGRiYmJjMmRiMDRkZThlZjkyZThlZmMxNDFmYmVjYWE2Mjg3YzU5NDc0ZTZiYzA1ZDk5YjI5NjRmYTA5MGMzYTIyMzNiYTE4NjUxNWJlN2VkMWY2MTI5NzBjZWUyZDdhZmI4MWJkZDc2MjE3MDQ4MWNkMDA2OTEyN2Q1YjA1YWE5OTNiNGVhOTg4ZDhmZGRjMTg2ZmZiN2RjOTBhNmMwOGY0ZGY0MzVjOTM0MDYzMTk5ZmZmZmZmZmZmZmZmZmZmZlwiXG4gICAgfSxcbiAgICBcIm1vZHAxN1wiOiB7XG4gICAgICAgIFwiZ2VuXCI6IFwiMDJcIixcbiAgICAgICAgXCJwcmltZVwiOiBcImZmZmZmZmZmZmZmZmZmZmZjOTBmZGFhMjIxNjhjMjM0YzRjNjYyOGI4MGRjMWNkMTI5MDI0ZTA4OGE2N2NjNzQwMjBiYmVhNjNiMTM5YjIyNTE0YTA4Nzk4ZTM0MDRkZGVmOTUxOWIzY2QzYTQzMWIzMDJiMGE2ZGYyNWYxNDM3NGZlMTM1NmQ2ZDUxYzI0NWU0ODViNTc2NjI1ZTdlYzZmNDRjNDJlOWE2MzdlZDZiMGJmZjVjYjZmNDA2YjdlZGVlMzg2YmZiNWE4OTlmYTVhZTlmMjQxMTdjNGIxZmU2NDkyODY2NTFlY2U0NWIzZGMyMDA3Y2I4YTE2M2JmMDU5OGRhNDgzNjFjNTVkMzlhNjkxNjNmYThmZDI0Y2Y1ZjgzNjU1ZDIzZGNhM2FkOTYxYzYyZjM1NjIwODU1MmJiOWVkNTI5MDc3MDk2OTY2ZDY3MGMzNTRlNGFiYzk4MDRmMTc0NmMwOGNhMTgyMTdjMzI5MDVlNDYyZTM2Y2UzYmUzOWU3NzJjMTgwZTg2MDM5YjI3ODNhMmVjMDdhMjhmYjVjNTVkZjA2ZjRjNTJjOWRlMmJjYmY2OTU1ODE3MTgzOTk1NDk3Y2VhOTU2YWU1MTVkMjI2MTg5OGZhMDUxMDE1NzI4ZTVhOGFhYWM0MmRhZDMzMTcwZDA0NTA3YTMzYTg1NTIxYWJkZjFjYmE2NGVjZmI4NTA0NThkYmVmMGE4YWVhNzE1NzVkMDYwYzdkYjM5NzBmODVhNmUxZTRjN2FiZjVhZThjZGIwOTMzZDcxZThjOTRlMDRhMjU2MTlkY2VlM2QyMjYxYWQyZWU2YmYxMmZmYTA2ZDk4YTA4NjRkODc2MDI3MzNlYzg2YTY0NTIxZjJiMTgxNzdiMjAwY2JiZTExNzU3N2E2MTVkNmM3NzA5ODhjMGJhZDk0NmUyMDhlMjRmYTA3NGU1YWIzMTQzZGI1YmZjZTBmZDEwOGU0YjgyZDEyMGE5MjEwODAxMWE3MjNjMTJhNzg3ZTZkNzg4NzE5YTEwYmRiYTViMjY5OWMzMjcxODZhZjRlMjNjMWE5NDY4MzRiNjE1MGJkYTI1ODNlOWNhMmFkNDRjZThkYmJiYzJkYjA0ZGU4ZWY5MmU4ZWZjMTQxZmJlY2FhNjI4N2M1OTQ3NGU2YmMwNWQ5OWIyOTY0ZmEwOTBjM2EyMjMzYmExODY1MTViZTdlZDFmNjEyOTcwY2VlMmQ3YWZiODFiZGQ3NjIxNzA0ODFjZDAwNjkxMjdkNWIwNWFhOTkzYjRlYTk4OGQ4ZmRkYzE4NmZmYjdkYzkwYTZjMDhmNGRmNDM1YzkzNDAyODQ5MjM2YzNmYWI0ZDI3YzcwMjZjMWQ0ZGNiMjYwMjY0NmRlYzk3NTFlNzYzZGJhMzdiZGY4ZmY5NDA2YWQ5ZTUzMGVlNWRiMzgyZjQxMzAwMWFlYjA2YTUzZWQ5MDI3ZDgzMTE3OTcyN2IwODY1YTg5MThkYTNlZGJlYmNmOWIxNGVkNDRjZTZjYmFjZWQ0YmIxYmRiN2YxNDQ3ZTZjYzI1NGIzMzIwNTE1MTJiZDdhZjQyNmZiOGY0MDEzNzhjZDJiZjU5ODNjYTAxYzY0YjkyZWNmMDMyZWExNWQxNzIxZDAzZjQ4MmQ3Y2U2ZTc0ZmVmNmQ1NWU3MDJmNDY5ODBjODJiNWE4NDAzMTkwMGIxYzllNTllN2M5N2ZiZWM3ZThmMzIzYTk3YTdlMzZjYzg4YmUwZjFkNDViN2ZmNTg1YWM1NGJkNDA3YjIyYjQxNTRhYWNjOGY2ZDdlYmY0OGUxZDgxNGNjNWVkMjBmODAzN2UwYTc5NzE1ZWVmMjliZTMyODA2YTFkNThiYjdjNWRhNzZmNTUwYWEzZDhhMWZiZmYwZWIxOWNjYjFhMzEzZDU1Y2RhNTZjOWVjMmVmMjk2MzIzODdmZThkNzZlM2MwNDY4MDQzZThmNjYzZjQ4NjBlZTEyYmYyZDViMGI3NDc0ZDZlNjk0ZjkxZTZkY2M0MDI0ZmZmZmZmZmZmZmZmZmZmZlwiXG4gICAgfSxcbiAgICBcIm1vZHAxOFwiOiB7XG4gICAgICAgIFwiZ2VuXCI6IFwiMDJcIixcbiAgICAgICAgXCJwcmltZVwiOiBcImZmZmZmZmZmZmZmZmZmZmZjOTBmZGFhMjIxNjhjMjM0YzRjNjYyOGI4MGRjMWNkMTI5MDI0ZTA4OGE2N2NjNzQwMjBiYmVhNjNiMTM5YjIyNTE0YTA4Nzk4ZTM0MDRkZGVmOTUxOWIzY2QzYTQzMWIzMDJiMGE2ZGYyNWYxNDM3NGZlMTM1NmQ2ZDUxYzI0NWU0ODViNTc2NjI1ZTdlYzZmNDRjNDJlOWE2MzdlZDZiMGJmZjVjYjZmNDA2YjdlZGVlMzg2YmZiNWE4OTlmYTVhZTlmMjQxMTdjNGIxZmU2NDkyODY2NTFlY2U0NWIzZGMyMDA3Y2I4YTE2M2JmMDU5OGRhNDgzNjFjNTVkMzlhNjkxNjNmYThmZDI0Y2Y1ZjgzNjU1ZDIzZGNhM2FkOTYxYzYyZjM1NjIwODU1MmJiOWVkNTI5MDc3MDk2OTY2ZDY3MGMzNTRlNGFiYzk4MDRmMTc0NmMwOGNhMTgyMTdjMzI5MDVlNDYyZTM2Y2UzYmUzOWU3NzJjMTgwZTg2MDM5YjI3ODNhMmVjMDdhMjhmYjVjNTVkZjA2ZjRjNTJjOWRlMmJjYmY2OTU1ODE3MTgzOTk1NDk3Y2VhOTU2YWU1MTVkMjI2MTg5OGZhMDUxMDE1NzI4ZTVhOGFhYWM0MmRhZDMzMTcwZDA0NTA3YTMzYTg1NTIxYWJkZjFjYmE2NGVjZmI4NTA0NThkYmVmMGE4YWVhNzE1NzVkMDYwYzdkYjM5NzBmODVhNmUxZTRjN2FiZjVhZThjZGIwOTMzZDcxZThjOTRlMDRhMjU2MTlkY2VlM2QyMjYxYWQyZWU2YmYxMmZmYTA2ZDk4YTA4NjRkODc2MDI3MzNlYzg2YTY0NTIxZjJiMTgxNzdiMjAwY2JiZTExNzU3N2E2MTVkNmM3NzA5ODhjMGJhZDk0NmUyMDhlMjRmYTA3NGU1YWIzMTQzZGI1YmZjZTBmZDEwOGU0YjgyZDEyMGE5MjEwODAxMWE3MjNjMTJhNzg3ZTZkNzg4NzE5YTEwYmRiYTViMjY5OWMzMjcxODZhZjRlMjNjMWE5NDY4MzRiNjE1MGJkYTI1ODNlOWNhMmFkNDRjZThkYmJiYzJkYjA0ZGU4ZWY5MmU4ZWZjMTQxZmJlY2FhNjI4N2M1OTQ3NGU2YmMwNWQ5OWIyOTY0ZmEwOTBjM2EyMjMzYmExODY1MTViZTdlZDFmNjEyOTcwY2VlMmQ3YWZiODFiZGQ3NjIxNzA0ODFjZDAwNjkxMjdkNWIwNWFhOTkzYjRlYTk4OGQ4ZmRkYzE4NmZmYjdkYzkwYTZjMDhmNGRmNDM1YzkzNDAyODQ5MjM2YzNmYWI0ZDI3YzcwMjZjMWQ0ZGNiMjYwMjY0NmRlYzk3NTFlNzYzZGJhMzdiZGY4ZmY5NDA2YWQ5ZTUzMGVlNWRiMzgyZjQxMzAwMWFlYjA2YTUzZWQ5MDI3ZDgzMTE3OTcyN2IwODY1YTg5MThkYTNlZGJlYmNmOWIxNGVkNDRjZTZjYmFjZWQ0YmIxYmRiN2YxNDQ3ZTZjYzI1NGIzMzIwNTE1MTJiZDdhZjQyNmZiOGY0MDEzNzhjZDJiZjU5ODNjYTAxYzY0YjkyZWNmMDMyZWExNWQxNzIxZDAzZjQ4MmQ3Y2U2ZTc0ZmVmNmQ1NWU3MDJmNDY5ODBjODJiNWE4NDAzMTkwMGIxYzllNTllN2M5N2ZiZWM3ZThmMzIzYTk3YTdlMzZjYzg4YmUwZjFkNDViN2ZmNTg1YWM1NGJkNDA3YjIyYjQxNTRhYWNjOGY2ZDdlYmY0OGUxZDgxNGNjNWVkMjBmODAzN2UwYTc5NzE1ZWVmMjliZTMyODA2YTFkNThiYjdjNWRhNzZmNTUwYWEzZDhhMWZiZmYwZWIxOWNjYjFhMzEzZDU1Y2RhNTZjOWVjMmVmMjk2MzIzODdmZThkNzZlM2MwNDY4MDQzZThmNjYzZjQ4NjBlZTEyYmYyZDViMGI3NDc0ZDZlNjk0ZjkxZTZkYmUxMTU5NzRhMzkyNmYxMmZlZTVlNDM4Nzc3Y2I2YTkzMmRmOGNkOGJlYzRkMDczYjkzMWJhM2JjODMyYjY4ZDlkZDMwMDc0MWZhN2JmOGFmYzQ3ZWQyNTc2ZjY5MzZiYTQyNDY2M2FhYjYzOWM1YWU0ZjU2ODM0MjNiNDc0MmJmMWM5NzgyMzhmMTZjYmUzOWQ2NTJkZTNmZGI4YmVmYzg0OGFkOTIyMjIyZTA0YTQwMzdjMDcxM2ViNTdhODFhMjNmMGM3MzQ3M2ZjNjQ2Y2VhMzA2YjRiY2JjODg2MmY4Mzg1ZGRmYTlkNGI3ZmEyYzA4N2U4Nzk2ODMzMDNlZDViZGQzYTA2MmIzY2Y1YjNhMjc4YTY2ZDJhMTNmODNmNDRmODJkZGYzMTBlZTA3NGFiNmEzNjQ1OTdlODk5YTAyNTVkYzE2NGYzMWNjNTA4NDY4NTFkZjlhYjQ4MTk1ZGVkN2VhMWIxZDUxMGJkN2VlNzRkNzNmYWYzNmJjMzFlY2ZhMjY4MzU5MDQ2ZjRlYjg3OWY5MjQwMDk0MzhiNDgxYzZjZDc4ODlhMDAyZWQ1ZWUzODJiYzkxOTBkYTZmYzAyNmU0Nzk1NThlNDQ3NTY3N2U5YWE5ZTMwNTBlMjc2NTY5NGRmYzgxZjU2ZTg4MGI5NmU3MTYwYzk4MGRkOThlZGQzZGZmZmZmZmZmZmZmZmZmZmZmXCJcbiAgICB9XG59IiwidmFyIGJuID0gcmVxdWlyZSgnYm4uanMnKTtcbnZhciBicm9yYW5kID0gcmVxdWlyZSgnYnJvcmFuZCcpO1xuXG5mdW5jdGlvbiBNaWxsZXJSYWJpbihyYW5kKSB7XG4gIHRoaXMucmFuZCA9IHJhbmQgfHwgbmV3IGJyb3JhbmQuUmFuZCgpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBNaWxsZXJSYWJpbjtcblxuTWlsbGVyUmFiaW4uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHJhbmQpIHtcbiAgcmV0dXJuIG5ldyBNaWxsZXJSYWJpbihyYW5kKTtcbn07XG5cbk1pbGxlclJhYmluLnByb3RvdHlwZS5fcmFuZCA9IGZ1bmN0aW9uIF9yYW5kKG4pIHtcbiAgdmFyIGxlbiA9IG4uYml0TGVuZ3RoKCk7XG4gIHZhciBidWYgPSB0aGlzLnJhbmQuZ2VuZXJhdGUoTWF0aC5jZWlsKGxlbiAvIDgpKTtcblxuICAvLyBTZXQgbG93IGJpdHNcbiAgYnVmWzBdIHw9IDM7XG5cbiAgLy8gTWFzayBoaWdoIGJpdHNcbiAgdmFyIG1hc2sgPSBsZW4gJiAweDc7XG4gIGlmIChtYXNrICE9PSAwKVxuICAgIGJ1ZltidWYubGVuZ3RoIC0gMV0gPj49IDcgLSBtYXNrO1xuXG4gIHJldHVybiBuZXcgYm4oYnVmKTtcbn1cblxuTWlsbGVyUmFiaW4ucHJvdG90eXBlLnRlc3QgPSBmdW5jdGlvbiB0ZXN0KG4sIGssIGNiKSB7XG4gIHZhciBsZW4gPSBuLmJpdExlbmd0aCgpO1xuICB2YXIgcmVkID0gYm4ubW9udChuKTtcbiAgdmFyIHJvbmUgPSBuZXcgYm4oMSkudG9SZWQocmVkKTtcblxuICBpZiAoIWspXG4gICAgayA9IE1hdGgubWF4KDEsIChsZW4gLyA0OCkgfCAwKTtcblxuICAvLyBGaW5kIGQgYW5kIHMsIChuIC0gMSkgPSAoMiBeIHMpICogZDtcbiAgdmFyIG4xID0gbi5zdWJuKDEpO1xuICB2YXIgbjIgPSBuMS5zdWJuKDEpO1xuICBmb3IgKHZhciBzID0gMDsgIW4xLnRlc3RuKHMpOyBzKyspIHt9XG4gIHZhciBkID0gbi5zaHJuKHMpO1xuXG4gIHZhciBybjEgPSBuMS50b1JlZChyZWQpO1xuXG4gIHZhciBwcmltZSA9IHRydWU7XG4gIGZvciAoOyBrID4gMDsgay0tKSB7XG4gICAgdmFyIGEgPSB0aGlzLl9yYW5kKG4yKTtcbiAgICBpZiAoY2IpXG4gICAgICBjYihhKTtcblxuICAgIHZhciB4ID0gYS50b1JlZChyZWQpLnJlZFBvdyhkKTtcbiAgICBpZiAoeC5jbXAocm9uZSkgPT09IDAgfHwgeC5jbXAocm4xKSA9PT0gMClcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCBzOyBpKyspIHtcbiAgICAgIHggPSB4LnJlZFNxcigpO1xuXG4gICAgICBpZiAoeC5jbXAocm9uZSkgPT09IDApXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIGlmICh4LmNtcChybjEpID09PSAwKVxuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoaSA9PT0gcylcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBwcmltZTtcbn07XG5cbk1pbGxlclJhYmluLnByb3RvdHlwZS5nZXREaXZpc29yID0gZnVuY3Rpb24gZ2V0RGl2aXNvcihuLCBrKSB7XG4gIHZhciBsZW4gPSBuLmJpdExlbmd0aCgpO1xuICB2YXIgcmVkID0gYm4ubW9udChuKTtcbiAgdmFyIHJvbmUgPSBuZXcgYm4oMSkudG9SZWQocmVkKTtcblxuICBpZiAoIWspXG4gICAgayA9IE1hdGgubWF4KDEsIChsZW4gLyA0OCkgfCAwKTtcblxuICAvLyBGaW5kIGQgYW5kIHMsIChuIC0gMSkgPSAoMiBeIHMpICogZDtcbiAgdmFyIG4xID0gbi5zdWJuKDEpO1xuICB2YXIgbjIgPSBuMS5zdWJuKDEpO1xuICBmb3IgKHZhciBzID0gMDsgIW4xLnRlc3RuKHMpOyBzKyspIHt9XG4gIHZhciBkID0gbi5zaHJuKHMpO1xuXG4gIHZhciBybjEgPSBuMS50b1JlZChyZWQpO1xuXG4gIGZvciAoOyBrID4gMDsgay0tKSB7XG4gICAgdmFyIGEgPSB0aGlzLl9yYW5kKG4yKTtcblxuICAgIHZhciBnID0gbi5nY2QoYSk7XG4gICAgaWYgKGcuY21wbigxKSAhPT0gMClcbiAgICAgIHJldHVybiBnO1xuXG4gICAgdmFyIHggPSBhLnRvUmVkKHJlZCkucmVkUG93KGQpO1xuICAgIGlmICh4LmNtcChyb25lKSA9PT0gMCB8fCB4LmNtcChybjEpID09PSAwKVxuICAgICAgY29udGludWU7XG5cbiAgICBmb3IgKHZhciBpID0gMTsgaSA8IHM7IGkrKykge1xuICAgICAgeCA9IHgucmVkU3FyKCk7XG5cbiAgICAgIGlmICh4LmNtcChyb25lKSA9PT0gMClcbiAgICAgICAgcmV0dXJuIHguZnJvbVJlZCgpLnN1Ym4oMSkuZ2NkKG4pO1xuICAgICAgaWYgKHguY21wKHJuMSkgPT09IDApXG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGlmIChpID09PSBzKSB7XG4gICAgICB4ID0geC5yZWRTcXIoKTtcbiAgICAgIHJldHVybiB4LmZyb21SZWQoKS5zdWJuKDEpLmdjZChuKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59O1xuIiwidmFyIGNyZWF0ZUhtYWMgPSByZXF1aXJlKCdjcmVhdGUtaG1hYycpXG52YXIgTUFYX0FMTE9DID0gTWF0aC5wb3coMiwgMzApIC0gMSAvLyBkZWZhdWx0IGluIGlvanNcblxuZXhwb3J0cy5wYmtkZjIgPSBwYmtkZjJcbmZ1bmN0aW9uIHBia2RmMiAocGFzc3dvcmQsIHNhbHQsIGl0ZXJhdGlvbnMsIGtleWxlbiwgZGlnZXN0LCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIGRpZ2VzdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNhbGxiYWNrID0gZGlnZXN0XG4gICAgZGlnZXN0ID0gdW5kZWZpbmVkXG4gIH1cblxuICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdObyBjYWxsYmFjayBwcm92aWRlZCB0byBwYmtkZjInKVxuICB9XG5cbiAgdmFyIHJlc3VsdCA9IHBia2RmMlN5bmMocGFzc3dvcmQsIHNhbHQsIGl0ZXJhdGlvbnMsIGtleWxlbiwgZGlnZXN0KVxuICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBjYWxsYmFjayh1bmRlZmluZWQsIHJlc3VsdClcbiAgfSlcbn1cblxuZXhwb3J0cy5wYmtkZjJTeW5jID0gcGJrZGYyU3luY1xuZnVuY3Rpb24gcGJrZGYyU3luYyAocGFzc3dvcmQsIHNhbHQsIGl0ZXJhdGlvbnMsIGtleWxlbiwgZGlnZXN0KSB7XG4gIGlmICh0eXBlb2YgaXRlcmF0aW9ucyAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJdGVyYXRpb25zIG5vdCBhIG51bWJlcicpXG4gIH1cblxuICBpZiAoaXRlcmF0aW9ucyA8IDApIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdCYWQgaXRlcmF0aW9ucycpXG4gIH1cblxuICBpZiAodHlwZW9mIGtleWxlbiAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdLZXkgbGVuZ3RoIG5vdCBhIG51bWJlcicpXG4gIH1cblxuICBpZiAoa2V5bGVuIDwgMCB8fCBrZXlsZW4gPiBNQVhfQUxMT0MpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdCYWQga2V5IGxlbmd0aCcpXG4gIH1cblxuICBkaWdlc3QgPSBkaWdlc3QgfHwgJ3NoYTEnXG5cbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIocGFzc3dvcmQpKSBwYXNzd29yZCA9IG5ldyBCdWZmZXIocGFzc3dvcmQsICdiaW5hcnknKVxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihzYWx0KSkgc2FsdCA9IG5ldyBCdWZmZXIoc2FsdCwgJ2JpbmFyeScpXG5cbiAgdmFyIGhMZW5cbiAgdmFyIGwgPSAxXG4gIHZhciBESyA9IG5ldyBCdWZmZXIoa2V5bGVuKVxuICB2YXIgYmxvY2sxID0gbmV3IEJ1ZmZlcihzYWx0Lmxlbmd0aCArIDQpXG4gIHNhbHQuY29weShibG9jazEsIDAsIDAsIHNhbHQubGVuZ3RoKVxuXG4gIHZhciByXG4gIHZhciBUXG5cbiAgZm9yICh2YXIgaSA9IDE7IGkgPD0gbDsgaSsrKSB7XG4gICAgYmxvY2sxLndyaXRlVUludDMyQkUoaSwgc2FsdC5sZW5ndGgpXG4gICAgdmFyIFUgPSBjcmVhdGVIbWFjKGRpZ2VzdCwgcGFzc3dvcmQpLnVwZGF0ZShibG9jazEpLmRpZ2VzdCgpXG5cbiAgICBpZiAoIWhMZW4pIHtcbiAgICAgIGhMZW4gPSBVLmxlbmd0aFxuICAgICAgVCA9IG5ldyBCdWZmZXIoaExlbilcbiAgICAgIGwgPSBNYXRoLmNlaWwoa2V5bGVuIC8gaExlbilcbiAgICAgIHIgPSBrZXlsZW4gLSAobCAtIDEpICogaExlblxuICAgIH1cblxuICAgIFUuY29weShULCAwLCAwLCBoTGVuKVxuXG4gICAgZm9yICh2YXIgaiA9IDE7IGogPCBpdGVyYXRpb25zOyBqKyspIHtcbiAgICAgIFUgPSBjcmVhdGVIbWFjKGRpZ2VzdCwgcGFzc3dvcmQpLnVwZGF0ZShVKS5kaWdlc3QoKVxuXG4gICAgICBmb3IgKHZhciBrID0gMDsgayA8IGhMZW47IGsrKykge1xuICAgICAgICBUW2tdIF49IFVba11cbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZGVzdFBvcyA9IChpIC0gMSkgKiBoTGVuXG4gICAgdmFyIGxlbiA9IChpID09PSBsID8gciA6IGhMZW4pXG4gICAgVC5jb3B5KERLLCBkZXN0UG9zLCAwLCBsZW4pXG4gIH1cblxuICByZXR1cm4gREtcbn1cbiIsImV4cG9ydHMucHVibGljRW5jcnlwdCA9IHJlcXVpcmUoJy4vcHVibGljRW5jcnlwdCcpO1xuZXhwb3J0cy5wcml2YXRlRGVjcnlwdCA9IHJlcXVpcmUoJy4vcHJpdmF0ZURlY3J5cHQnKTtcblxuZXhwb3J0cy5wcml2YXRlRW5jcnlwdCA9IGZ1bmN0aW9uIHByaXZhdGVFbmNyeXB0KGtleSwgYnVmKSB7XG4gIHJldHVybiBleHBvcnRzLnB1YmxpY0VuY3J5cHQoa2V5LCBidWYsIHRydWUpO1xufTtcblxuZXhwb3J0cy5wdWJsaWNEZWNyeXB0ID0gZnVuY3Rpb24gcHVibGljRGVjcnlwdChrZXksIGJ1Zikge1xuICByZXR1cm4gZXhwb3J0cy5wcml2YXRlRGVjcnlwdChrZXksIGJ1ZiwgdHJ1ZSk7XG59OyIsInZhciBjcmVhdGVIYXNoID0gcmVxdWlyZSgnY3JlYXRlLWhhc2gnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHNlZWQsIGxlbikge1xuICB2YXIgdCA9IG5ldyBCdWZmZXIoJycpO1xuICB2YXIgIGkgPSAwLCBjO1xuICB3aGlsZSAodC5sZW5ndGggPCBsZW4pIHtcbiAgICBjID0gaTJvcHMoaSsrKTtcbiAgICB0ID0gQnVmZmVyLmNvbmNhdChbdCwgY3JlYXRlSGFzaCgnc2hhMScpLnVwZGF0ZShzZWVkKS51cGRhdGUoYykuZGlnZXN0KCldKTtcbiAgfVxuICByZXR1cm4gdC5zbGljZSgwLCBsZW4pO1xufTtcblxuZnVuY3Rpb24gaTJvcHMoYykge1xuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcig0KTtcbiAgb3V0LndyaXRlVUludDMyQkUoYywwKTtcbiAgcmV0dXJuIG91dDtcbn0iLCJ2YXIgYm4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIHJhbmRvbUJ5dGVzID0gcmVxdWlyZSgncmFuZG9tYnl0ZXMnKTtcbm1vZHVsZS5leHBvcnRzID0gY3J0O1xuZnVuY3Rpb24gYmxpbmQocHJpdikge1xuICB2YXIgciA9IGdldHIocHJpdik7XG4gIHZhciBibGluZGVyID0gci50b1JlZChibi5tb250KHByaXYubW9kdWx1cykpXG4gIC5yZWRQb3cobmV3IGJuKHByaXYucHVibGljRXhwb25lbnQpKS5mcm9tUmVkKCk7XG4gIHJldHVybiB7XG4gICAgYmxpbmRlcjogYmxpbmRlcixcbiAgICB1bmJsaW5kZXI6ci5pbnZtKHByaXYubW9kdWx1cylcbiAgfTtcbn1cbmZ1bmN0aW9uIGNydChtc2csIHByaXYpIHtcbiAgdmFyIGJsaW5kcyA9IGJsaW5kKHByaXYpO1xuICB2YXIgbGVuID0gcHJpdi5tb2R1bHVzLmJ5dGVMZW5ndGgoKTtcbiAgdmFyIG1vZCA9IGJuLm1vbnQocHJpdi5tb2R1bHVzKTtcbiAgdmFyIGJsaW5kZWQgPSBuZXcgYm4obXNnKS5tdWwoYmxpbmRzLmJsaW5kZXIpLnVtb2QocHJpdi5tb2R1bHVzKTtcbiAgdmFyIGMxID0gYmxpbmRlZC50b1JlZChibi5tb250KHByaXYucHJpbWUxKSk7XG4gIHZhciBjMiA9IGJsaW5kZWQudG9SZWQoYm4ubW9udChwcml2LnByaW1lMikpO1xuICB2YXIgcWludiA9IHByaXYuY29lZmZpY2llbnQ7XG4gIHZhciBwID0gcHJpdi5wcmltZTE7XG4gIHZhciBxID0gcHJpdi5wcmltZTI7XG4gIHZhciBtMSA9IGMxLnJlZFBvdyhwcml2LmV4cG9uZW50MSk7XG4gIHZhciBtMiA9IGMyLnJlZFBvdyhwcml2LmV4cG9uZW50Mik7XG4gIG0xID0gbTEuZnJvbVJlZCgpO1xuICBtMiA9IG0yLmZyb21SZWQoKTtcbiAgdmFyIGggPSBtMS5pc3ViKG0yKS5pbXVsKHFpbnYpLnVtb2QocCk7XG4gIGguaW11bChxKTtcbiAgbTIuaWFkZChoKTtcbiAgcmV0dXJuIG5ldyBCdWZmZXIobTIuaW11bChibGluZHMudW5ibGluZGVyKS51bW9kKHByaXYubW9kdWx1cykudG9BcnJheShmYWxzZSwgbGVuKSk7XG59XG5jcnQuZ2V0ciA9IGdldHI7XG5mdW5jdGlvbiBnZXRyKHByaXYpIHtcbiAgdmFyIGxlbiA9IHByaXYubW9kdWx1cy5ieXRlTGVuZ3RoKCk7XG4gIHZhciByID0gbmV3IGJuKHJhbmRvbUJ5dGVzKGxlbikpO1xuICB3aGlsZSAoci5jbXAocHJpdi5tb2R1bHVzKSA+PSAgMCB8fCAhci51bW9kKHByaXYucHJpbWUxKSB8fCAhci51bW9kKHByaXYucHJpbWUyKSkge1xuICAgIHIgPSBuZXcgYm4ocmFuZG9tQnl0ZXMobGVuKSk7XG4gIH1cbiAgcmV0dXJuIHI7XG59XG4iLCIvLyBhZGFwdGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2FwYXRpbC9wZW1zdHJpcFxudmFyIGZpbmRQcm9jID0gL1Byb2MtVHlwZTogNCxFTkNSWVBURURcXHI/XFxuREVLLUluZm86IEFFUy0oKD86MTI4KXwoPzoxOTIpfCg/OjI1NikpLUNCQywoWzAtOUEtSF0rKVxccj9cXG5cXHI/XFxuKFswLTlBLXpcXG5cXHJcXCtcXC9cXD1dKylcXHI/XFxuL21cbnZhciBzdGFydFJlZ2V4ID0gL14tLS0tLUJFR0lOICguKikgS0VZLS0tLS1cXHI/XFxuL21cbnZhciBmdWxsUmVnZXggPSAvXi0tLS0tQkVHSU4gKC4qKSBLRVktLS0tLVxccj9cXG4oWzAtOUEtelxcblxcclxcK1xcL1xcPV0rKVxccj9cXG4tLS0tLUVORCBcXDEgS0VZLS0tLS0kL21cbnZhciBldnAgPSByZXF1aXJlKCdldnBfYnl0ZXN0b2tleScpXG52YXIgY2lwaGVycyA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktYWVzJylcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9rZXksIHBhc3N3b3JkKSB7XG4gIHZhciBrZXkgPSBva2V5LnRvU3RyaW5nKClcbiAgdmFyIG1hdGNoID0ga2V5Lm1hdGNoKGZpbmRQcm9jKVxuICB2YXIgZGVjcnlwdGVkXG4gIGlmICghbWF0Y2gpIHtcbiAgICB2YXIgbWF0Y2gyID0ga2V5Lm1hdGNoKGZ1bGxSZWdleClcbiAgICBkZWNyeXB0ZWQgPSBuZXcgQnVmZmVyKG1hdGNoMlsyXS5yZXBsYWNlKC9cXHI/XFxuL2csICcnKSwgJ2Jhc2U2NCcpXG4gIH0gZWxzZSB7XG4gICAgdmFyIHN1aXRlID0gJ2FlcycgKyBtYXRjaFsxXVxuICAgIHZhciBpdiA9IG5ldyBCdWZmZXIobWF0Y2hbMl0sICdoZXgnKVxuICAgIHZhciBjaXBoZXJUZXh0ID0gbmV3IEJ1ZmZlcihtYXRjaFszXS5yZXBsYWNlKC9cXHI/XFxuL2csICcnKSwgJ2Jhc2U2NCcpXG4gICAgdmFyIGNpcGhlcktleSA9IGV2cChwYXNzd29yZCwgaXYuc2xpY2UoMCwgOCksIHBhcnNlSW50KG1hdGNoWzFdLCAxMCkpLmtleVxuICAgIHZhciBvdXQgPSBbXVxuICAgIHZhciBjaXBoZXIgPSBjaXBoZXJzLmNyZWF0ZURlY2lwaGVyaXYoc3VpdGUsIGNpcGhlcktleSwgaXYpXG4gICAgb3V0LnB1c2goY2lwaGVyLnVwZGF0ZShjaXBoZXJUZXh0KSlcbiAgICBvdXQucHVzaChjaXBoZXIuZmluYWwoKSlcbiAgICBkZWNyeXB0ZWQgPSBCdWZmZXIuY29uY2F0KG91dClcbiAgfVxuICB2YXIgdGFnID0ga2V5Lm1hdGNoKHN0YXJ0UmVnZXgpWzFdICsgJyBLRVknXG4gIHJldHVybiB7XG4gICAgdGFnOiB0YWcsXG4gICAgZGF0YTogZGVjcnlwdGVkXG4gIH1cbn1cbiIsInZhciBhc24xID0gcmVxdWlyZSgnLi9hc24xJylcbnZhciBhZXNpZCA9IHJlcXVpcmUoJy4vYWVzaWQuanNvbicpXG52YXIgZml4UHJvYyA9IHJlcXVpcmUoJy4vZml4UHJvYycpXG52YXIgY2lwaGVycyA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktYWVzJylcbnZhciBjb21wYXQgPSByZXF1aXJlKCdwYmtkZjInKVxubW9kdWxlLmV4cG9ydHMgPSBwYXJzZUtleXNcblxuZnVuY3Rpb24gcGFyc2VLZXlzIChidWZmZXIpIHtcbiAgdmFyIHBhc3N3b3JkXG4gIGlmICh0eXBlb2YgYnVmZmVyID09PSAnb2JqZWN0JyAmJiAhQnVmZmVyLmlzQnVmZmVyKGJ1ZmZlcikpIHtcbiAgICBwYXNzd29yZCA9IGJ1ZmZlci5wYXNzcGhyYXNlXG4gICAgYnVmZmVyID0gYnVmZmVyLmtleVxuICB9XG4gIGlmICh0eXBlb2YgYnVmZmVyID09PSAnc3RyaW5nJykge1xuICAgIGJ1ZmZlciA9IG5ldyBCdWZmZXIoYnVmZmVyKVxuICB9XG5cbiAgdmFyIHN0cmlwcGVkID0gZml4UHJvYyhidWZmZXIsIHBhc3N3b3JkKVxuXG4gIHZhciB0eXBlID0gc3RyaXBwZWQudGFnXG4gIHZhciBkYXRhID0gc3RyaXBwZWQuZGF0YVxuICB2YXIgc3VidHlwZSwgbmRhdGFcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnUFVCTElDIEtFWSc6XG4gICAgICBuZGF0YSA9IGFzbjEuUHVibGljS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIHN1YnR5cGUgPSBuZGF0YS5hbGdvcml0aG0uYWxnb3JpdGhtLmpvaW4oJy4nKVxuICAgICAgc3dpdGNoIChzdWJ0eXBlKSB7XG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTEzNTQ5LjEuMS4xJzpcbiAgICAgICAgICByZXR1cm4gYXNuMS5SU0FQdWJsaWNLZXkuZGVjb2RlKG5kYXRhLnN1YmplY3RQdWJsaWNLZXkuZGF0YSwgJ2RlcicpXG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTAwNDUuMi4xJzpcbiAgICAgICAgICBuZGF0YS5zdWJqZWN0UHJpdmF0ZUtleSA9IG5kYXRhLnN1YmplY3RQdWJsaWNLZXlcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ2VjJyxcbiAgICAgICAgICAgIGRhdGE6IG5kYXRhXG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICcxLjIuODQwLjEwMDQwLjQuMSc6XG4gICAgICAgICAgbmRhdGEuYWxnb3JpdGhtLnBhcmFtcy5wdWJfa2V5ID0gYXNuMS5EU0FwYXJhbS5kZWNvZGUobmRhdGEuc3ViamVjdFB1YmxpY0tleS5kYXRhLCAnZGVyJylcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ2RzYScsXG4gICAgICAgICAgICBkYXRhOiBuZGF0YS5hbGdvcml0aG0ucGFyYW1zXG4gICAgICAgICAgfVxuICAgICAgICBkZWZhdWx0OiB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24ga2V5IGlkICcgKyBzdWJ0eXBlKVxuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGtleSB0eXBlICcgKyB0eXBlKVxuICAgIGNhc2UgJ0VOQ1JZUFRFRCBQUklWQVRFIEtFWSc6XG4gICAgICBkYXRhID0gYXNuMS5FbmNyeXB0ZWRQcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIGRhdGEgPSBkZWNyeXB0KGRhdGEsIHBhc3N3b3JkKVxuICAgICAgLy8gZmFsbHMgdGhyb3VnaFxuICAgIGNhc2UgJ1BSSVZBVEUgS0VZJzpcbiAgICAgIG5kYXRhID0gYXNuMS5Qcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIHN1YnR5cGUgPSBuZGF0YS5hbGdvcml0aG0uYWxnb3JpdGhtLmpvaW4oJy4nKVxuICAgICAgc3dpdGNoIChzdWJ0eXBlKSB7XG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTEzNTQ5LjEuMS4xJzpcbiAgICAgICAgICByZXR1cm4gYXNuMS5SU0FQcml2YXRlS2V5LmRlY29kZShuZGF0YS5zdWJqZWN0UHJpdmF0ZUtleSwgJ2RlcicpXG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTAwNDUuMi4xJzpcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3VydmU6IG5kYXRhLmFsZ29yaXRobS5jdXJ2ZSxcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IGFzbjEuRUNQcml2YXRlS2V5LmRlY29kZShuZGF0YS5zdWJqZWN0UHJpdmF0ZUtleSwgJ2RlcicpLnByaXZhdGVLZXlcbiAgICAgICAgICB9XG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTAwNDAuNC4xJzpcbiAgICAgICAgICBuZGF0YS5hbGdvcml0aG0ucGFyYW1zLnByaXZfa2V5ID0gYXNuMS5EU0FwYXJhbS5kZWNvZGUobmRhdGEuc3ViamVjdFByaXZhdGVLZXksICdkZXInKVxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAnZHNhJyxcbiAgICAgICAgICAgIHBhcmFtczogbmRhdGEuYWxnb3JpdGhtLnBhcmFtc1xuICAgICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGtleSBpZCAnICsgc3VidHlwZSlcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBrZXkgdHlwZSAnICsgdHlwZSlcbiAgICBjYXNlICdSU0EgUFVCTElDIEtFWSc6XG4gICAgICByZXR1cm4gYXNuMS5SU0FQdWJsaWNLZXkuZGVjb2RlKGRhdGEsICdkZXInKVxuICAgIGNhc2UgJ1JTQSBQUklWQVRFIEtFWSc6XG4gICAgICByZXR1cm4gYXNuMS5SU0FQcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICBjYXNlICdEU0EgUFJJVkFURSBLRVknOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2RzYScsXG4gICAgICAgIHBhcmFtczogYXNuMS5EU0FQcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIH1cbiAgICBjYXNlICdFQyBQUklWQVRFIEtFWSc6XG4gICAgICBkYXRhID0gYXNuMS5FQ1ByaXZhdGVLZXkuZGVjb2RlKGRhdGEsICdkZXInKVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY3VydmU6IGRhdGEucGFyYW1ldGVycy52YWx1ZSxcbiAgICAgICAgcHJpdmF0ZUtleTogZGF0YS5wcml2YXRlS2V5XG4gICAgICB9XG4gICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGtleSB0eXBlICcgKyB0eXBlKVxuICB9XG59XG5wYXJzZUtleXMuc2lnbmF0dXJlID0gYXNuMS5zaWduYXR1cmVcbmZ1bmN0aW9uIGRlY3J5cHQgKGRhdGEsIHBhc3N3b3JkKSB7XG4gIHZhciBzYWx0ID0gZGF0YS5hbGdvcml0aG0uZGVjcnlwdC5rZGUua2RlcGFyYW1zLnNhbHRcbiAgdmFyIGl0ZXJzID0gcGFyc2VJbnQoZGF0YS5hbGdvcml0aG0uZGVjcnlwdC5rZGUua2RlcGFyYW1zLml0ZXJzLnRvU3RyaW5nKCksIDEwKVxuICB2YXIgYWxnbyA9IGFlc2lkW2RhdGEuYWxnb3JpdGhtLmRlY3J5cHQuY2lwaGVyLmFsZ28uam9pbignLicpXVxuICB2YXIgaXYgPSBkYXRhLmFsZ29yaXRobS5kZWNyeXB0LmNpcGhlci5pdlxuICB2YXIgY2lwaGVyVGV4dCA9IGRhdGEuc3ViamVjdFByaXZhdGVLZXlcbiAgdmFyIGtleWxlbiA9IHBhcnNlSW50KGFsZ28uc3BsaXQoJy0nKVsxXSwgMTApIC8gOFxuICB2YXIga2V5ID0gY29tcGF0LnBia2RmMlN5bmMocGFzc3dvcmQsIHNhbHQsIGl0ZXJzLCBrZXlsZW4pXG4gIHZhciBjaXBoZXIgPSBjaXBoZXJzLmNyZWF0ZURlY2lwaGVyaXYoYWxnbywga2V5LCBpdilcbiAgdmFyIG91dCA9IFtdXG4gIG91dC5wdXNoKGNpcGhlci51cGRhdGUoY2lwaGVyVGV4dCkpXG4gIG91dC5wdXNoKGNpcGhlci5maW5hbCgpKVxuICByZXR1cm4gQnVmZmVyLmNvbmNhdChvdXQpXG59XG4iLCIvLyBiYXNlZCBvbiB0aGUgYWVzIGltcGxpbWVudGF0aW9uIGluIHRyaXBsZSBzZWNcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9rZXliYXNlL3RyaXBsZXNlY1xuXG4vLyB3aGljaCBpcyBpbiB0dXJuIGJhc2VkIG9uIHRoZSBvbmUgZnJvbSBjcnlwdG8tanNcbi8vIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzL1xuXG52YXIgdWludF9tYXggPSBNYXRoLnBvdygyLCAzMilcbmZ1bmN0aW9uIGZpeHVwX3VpbnQzMiAoeCkge1xuICB2YXIgcmV0LCB4X3Bvc1xuICByZXQgPSB4ID4gdWludF9tYXggfHwgeCA8IDAgPyAoeF9wb3MgPSBNYXRoLmFicyh4KSAlIHVpbnRfbWF4LCB4IDwgMCA/IHVpbnRfbWF4IC0geF9wb3MgOiB4X3BvcykgOiB4XG4gIHJldHVybiByZXRcbn1cbmZ1bmN0aW9uIHNjcnViX3ZlYyAodikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHYubGVuZ3RoOyB2KyspIHtcbiAgICB2W2ldID0gMFxuICB9XG4gIHJldHVybiBmYWxzZVxufVxuXG5mdW5jdGlvbiBHbG9iYWwgKCkge1xuICB0aGlzLlNCT1ggPSBbXVxuICB0aGlzLklOVl9TQk9YID0gW11cbiAgdGhpcy5TVUJfTUlYID0gW1tdLCBbXSwgW10sIFtdXVxuICB0aGlzLklOVl9TVUJfTUlYID0gW1tdLCBbXSwgW10sIFtdXVxuICB0aGlzLmluaXQoKVxuICB0aGlzLlJDT04gPSBbMHgwMCwgMHgwMSwgMHgwMiwgMHgwNCwgMHgwOCwgMHgxMCwgMHgyMCwgMHg0MCwgMHg4MCwgMHgxYiwgMHgzNl1cbn1cblxuR2xvYmFsLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgZCwgaSwgc3gsIHQsIHgsIHgyLCB4NCwgeDgsIHhpLCBfaVxuICBkID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgX2ksIF9yZXN1bHRzXG4gICAgX3Jlc3VsdHMgPSBbXVxuICAgIGZvciAoaSA9IF9pID0gMDsgX2kgPCAyNTY7IGkgPSArK19pKSB7XG4gICAgICBpZiAoaSA8IDEyOCkge1xuICAgICAgICBfcmVzdWx0cy5wdXNoKGkgPDwgMSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIF9yZXN1bHRzLnB1c2goKGkgPDwgMSkgXiAweDExYilcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIF9yZXN1bHRzXG4gIH0pKClcbiAgeCA9IDBcbiAgeGkgPSAwXG4gIGZvciAoaSA9IF9pID0gMDsgX2kgPCAyNTY7IGkgPSArK19pKSB7XG4gICAgc3ggPSB4aSBeICh4aSA8PCAxKSBeICh4aSA8PCAyKSBeICh4aSA8PCAzKSBeICh4aSA8PCA0KVxuICAgIHN4ID0gKHN4ID4+PiA4KSBeIChzeCAmIDB4ZmYpIF4gMHg2M1xuICAgIHRoaXMuU0JPWFt4XSA9IHN4XG4gICAgdGhpcy5JTlZfU0JPWFtzeF0gPSB4XG4gICAgeDIgPSBkW3hdXG4gICAgeDQgPSBkW3gyXVxuICAgIHg4ID0gZFt4NF1cbiAgICB0ID0gKGRbc3hdICogMHgxMDEpIF4gKHN4ICogMHgxMDEwMTAwKVxuICAgIHRoaXMuU1VCX01JWFswXVt4XSA9ICh0IDw8IDI0KSB8ICh0ID4+PiA4KVxuICAgIHRoaXMuU1VCX01JWFsxXVt4XSA9ICh0IDw8IDE2KSB8ICh0ID4+PiAxNilcbiAgICB0aGlzLlNVQl9NSVhbMl1beF0gPSAodCA8PCA4KSB8ICh0ID4+PiAyNClcbiAgICB0aGlzLlNVQl9NSVhbM11beF0gPSB0XG4gICAgdCA9ICh4OCAqIDB4MTAxMDEwMSkgXiAoeDQgKiAweDEwMDAxKSBeICh4MiAqIDB4MTAxKSBeICh4ICogMHgxMDEwMTAwKVxuICAgIHRoaXMuSU5WX1NVQl9NSVhbMF1bc3hdID0gKHQgPDwgMjQpIHwgKHQgPj4+IDgpXG4gICAgdGhpcy5JTlZfU1VCX01JWFsxXVtzeF0gPSAodCA8PCAxNikgfCAodCA+Pj4gMTYpXG4gICAgdGhpcy5JTlZfU1VCX01JWFsyXVtzeF0gPSAodCA8PCA4KSB8ICh0ID4+PiAyNClcbiAgICB0aGlzLklOVl9TVUJfTUlYWzNdW3N4XSA9IHRcbiAgICBpZiAoeCA9PT0gMCkge1xuICAgICAgeCA9IHhpID0gMVxuICAgIH0gZWxzZSB7XG4gICAgICB4ID0geDIgXiBkW2RbZFt4OCBeIHgyXV1dXG4gICAgICB4aSBePSBkW2RbeGldXVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG52YXIgRyA9IG5ldyBHbG9iYWwoKVxuXG5BRVMuYmxvY2tTaXplID0gNCAqIDRcblxuQUVTLnByb3RvdHlwZS5ibG9ja1NpemUgPSBBRVMuYmxvY2tTaXplXG5cbkFFUy5rZXlTaXplID0gMjU2IC8gOFxuXG5BRVMucHJvdG90eXBlLmtleVNpemUgPSBBRVMua2V5U2l6ZVxuXG5mdW5jdGlvbiBidWZmZXJUb0FycmF5IChidWYpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGggLyA0XG4gIHZhciBvdXQgPSBuZXcgQXJyYXkobGVuKVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXRbaV0gPSBidWYucmVhZFVJbnQzMkJFKGkgKiA0KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbmZ1bmN0aW9uIEFFUyAoa2V5KSB7XG4gIHRoaXMuX2tleSA9IGJ1ZmZlclRvQXJyYXkoa2V5KVxuICB0aGlzLl9kb1Jlc2V0KClcbn1cblxuQUVTLnByb3RvdHlwZS5fZG9SZXNldCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGludktzUm93LCBrZXlTaXplLCBrZXlXb3Jkcywga3NSb3csIGtzUm93cywgdFxuICBrZXlXb3JkcyA9IHRoaXMuX2tleVxuICBrZXlTaXplID0ga2V5V29yZHMubGVuZ3RoXG4gIHRoaXMuX25Sb3VuZHMgPSBrZXlTaXplICsgNlxuICBrc1Jvd3MgPSAodGhpcy5fblJvdW5kcyArIDEpICogNFxuICB0aGlzLl9rZXlTY2hlZHVsZSA9IFtdXG4gIGZvciAoa3NSb3cgPSAwOyBrc1JvdyA8IGtzUm93czsga3NSb3crKykge1xuICAgIHRoaXMuX2tleVNjaGVkdWxlW2tzUm93XSA9IGtzUm93IDwga2V5U2l6ZSA/IGtleVdvcmRzW2tzUm93XSA6ICh0ID0gdGhpcy5fa2V5U2NoZWR1bGVba3NSb3cgLSAxXSwgKGtzUm93ICUga2V5U2l6ZSkgPT09IDAgPyAodCA9ICh0IDw8IDgpIHwgKHQgPj4+IDI0KSwgdCA9IChHLlNCT1hbdCA+Pj4gMjRdIDw8IDI0KSB8IChHLlNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChHLlNCT1hbKHQgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBHLlNCT1hbdCAmIDB4ZmZdLCB0IF49IEcuUkNPTlsoa3NSb3cgLyBrZXlTaXplKSB8IDBdIDw8IDI0KSA6IGtleVNpemUgPiA2ICYmIGtzUm93ICUga2V5U2l6ZSA9PT0gNCA/IHQgPSAoRy5TQk9YW3QgPj4+IDI0XSA8PCAyNCkgfCAoRy5TQk9YWyh0ID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoRy5TQk9YWyh0ID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgRy5TQk9YW3QgJiAweGZmXSA6IHZvaWQgMCwgdGhpcy5fa2V5U2NoZWR1bGVba3NSb3cgLSBrZXlTaXplXSBeIHQpXG4gIH1cbiAgdGhpcy5faW52S2V5U2NoZWR1bGUgPSBbXVxuICBmb3IgKGludktzUm93ID0gMDsgaW52S3NSb3cgPCBrc1Jvd3M7IGludktzUm93KyspIHtcbiAgICBrc1JvdyA9IGtzUm93cyAtIGludktzUm93XG4gICAgdCA9IHRoaXMuX2tleVNjaGVkdWxlW2tzUm93IC0gKGludktzUm93ICUgNCA/IDAgOiA0KV1cbiAgICB0aGlzLl9pbnZLZXlTY2hlZHVsZVtpbnZLc1Jvd10gPSBpbnZLc1JvdyA8IDQgfHwga3NSb3cgPD0gNCA/IHQgOiBHLklOVl9TVUJfTUlYWzBdW0cuU0JPWFt0ID4+PiAyNF1dIF4gRy5JTlZfU1VCX01JWFsxXVtHLlNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdXSBeIEcuSU5WX1NVQl9NSVhbMl1bRy5TQk9YWyh0ID4+PiA4KSAmIDB4ZmZdXSBeIEcuSU5WX1NVQl9NSVhbM11bRy5TQk9YW3QgJiAweGZmXV1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG5BRVMucHJvdG90eXBlLmVuY3J5cHRCbG9jayA9IGZ1bmN0aW9uIChNKSB7XG4gIE0gPSBidWZmZXJUb0FycmF5KG5ldyBCdWZmZXIoTSkpXG4gIHZhciBvdXQgPSB0aGlzLl9kb0NyeXB0QmxvY2soTSwgdGhpcy5fa2V5U2NoZWR1bGUsIEcuU1VCX01JWCwgRy5TQk9YKVxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcigxNilcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzBdLCAwKVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMV0sIDQpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsyXSwgOClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzNdLCAxMilcbiAgcmV0dXJuIGJ1ZlxufVxuXG5BRVMucHJvdG90eXBlLmRlY3J5cHRCbG9jayA9IGZ1bmN0aW9uIChNKSB7XG4gIE0gPSBidWZmZXJUb0FycmF5KG5ldyBCdWZmZXIoTSkpXG4gIHZhciB0ZW1wID0gW01bM10sIE1bMV1dXG4gIE1bMV0gPSB0ZW1wWzBdXG4gIE1bM10gPSB0ZW1wWzFdXG4gIHZhciBvdXQgPSB0aGlzLl9kb0NyeXB0QmxvY2soTSwgdGhpcy5faW52S2V5U2NoZWR1bGUsIEcuSU5WX1NVQl9NSVgsIEcuSU5WX1NCT1gpXG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKDE2KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMF0sIDApXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFszXSwgNClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzJdLCA4KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMV0sIDEyKVxuICByZXR1cm4gYnVmXG59XG5cbkFFUy5wcm90b3R5cGUuc2NydWIgPSBmdW5jdGlvbiAoKSB7XG4gIHNjcnViX3ZlYyh0aGlzLl9rZXlTY2hlZHVsZSlcbiAgc2NydWJfdmVjKHRoaXMuX2ludktleVNjaGVkdWxlKVxuICBzY3J1Yl92ZWModGhpcy5fa2V5KVxufVxuXG5BRVMucHJvdG90eXBlLl9kb0NyeXB0QmxvY2sgPSBmdW5jdGlvbiAoTSwga2V5U2NoZWR1bGUsIFNVQl9NSVgsIFNCT1gpIHtcbiAgdmFyIGtzUm93LCBzMCwgczEsIHMyLCBzMywgdDAsIHQxLCB0MiwgdDNcblxuICBzMCA9IE1bMF0gXiBrZXlTY2hlZHVsZVswXVxuICBzMSA9IE1bMV0gXiBrZXlTY2hlZHVsZVsxXVxuICBzMiA9IE1bMl0gXiBrZXlTY2hlZHVsZVsyXVxuICBzMyA9IE1bM10gXiBrZXlTY2hlZHVsZVszXVxuICBrc1JvdyA9IDRcbiAgZm9yICh2YXIgcm91bmQgPSAxOyByb3VuZCA8IHRoaXMuX25Sb3VuZHM7IHJvdW5kKyspIHtcbiAgICB0MCA9IFNVQl9NSVhbMF1bczAgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMxID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMyID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMyAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MSA9IFNVQl9NSVhbMF1bczEgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMyID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMzID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMCAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MiA9IFNVQl9NSVhbMF1bczIgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMzID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMwID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMSAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MyA9IFNVQl9NSVhbMF1bczMgPj4+IDI0XSBeIFNVQl9NSVhbMV1bKHMwID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVhbMl1bKHMxID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWFszXVtzMiAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICBzMCA9IHQwXG4gICAgczEgPSB0MVxuICAgIHMyID0gdDJcbiAgICBzMyA9IHQzXG4gIH1cbiAgdDAgPSAoKFNCT1hbczAgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczEgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMiA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczMgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICB0MSA9ICgoU0JPWFtzMSA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMiA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMzID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMCAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gIHQyID0gKChTQk9YW3MyID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMzID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczAgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MxICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgdDMgPSAoKFNCT1hbczMgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczAgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMSA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczIgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICByZXR1cm4gW1xuICAgIGZpeHVwX3VpbnQzMih0MCksXG4gICAgZml4dXBfdWludDMyKHQxKSxcbiAgICBmaXh1cF91aW50MzIodDIpLFxuICAgIGZpeHVwX3VpbnQzMih0MylcbiAgXVxufVxuXG5leHBvcnRzLkFFUyA9IEFFU1xuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgR0hBU0ggPSByZXF1aXJlKCcuL2doYXNoJylcbnZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcbmluaGVyaXRzKFN0cmVhbUNpcGhlciwgVHJhbnNmb3JtKVxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW1DaXBoZXJcblxuZnVuY3Rpb24gU3RyZWFtQ2lwaGVyIChtb2RlLCBrZXksIGl2LCBkZWNyeXB0KSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTdHJlYW1DaXBoZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBTdHJlYW1DaXBoZXIobW9kZSwga2V5LCBpdilcbiAgfVxuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuICB0aGlzLl9maW5JRCA9IEJ1ZmZlci5jb25jYXQoW2l2LCBuZXcgQnVmZmVyKFswLCAwLCAwLCAxXSldKVxuICBpdiA9IEJ1ZmZlci5jb25jYXQoW2l2LCBuZXcgQnVmZmVyKFswLCAwLCAwLCAyXSldKVxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHRoaXMuX3ByZXYgPSBuZXcgQnVmZmVyKGl2Lmxlbmd0aClcbiAgdGhpcy5fY2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxuICB0aGlzLl9zZWNDYWNoZSA9IG5ldyBCdWZmZXIoJycpXG4gIHRoaXMuX2RlY3J5cHQgPSBkZWNyeXB0XG4gIHRoaXMuX2FsZW4gPSAwXG4gIHRoaXMuX2xlbiA9IDBcbiAgaXYuY29weSh0aGlzLl9wcmV2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxuICB2YXIgaCA9IG5ldyBCdWZmZXIoNClcbiAgaC5maWxsKDApXG4gIHRoaXMuX2doYXNoID0gbmV3IEdIQVNIKHRoaXMuX2NpcGhlci5lbmNyeXB0QmxvY2soaCkpXG4gIHRoaXMuX2F1dGhUYWcgPSBudWxsXG4gIHRoaXMuX2NhbGxlZCA9IGZhbHNlXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgaWYgKCF0aGlzLl9jYWxsZWQgJiYgdGhpcy5fYWxlbikge1xuICAgIHZhciBydW1wID0gMTYgLSAodGhpcy5fYWxlbiAlIDE2KVxuICAgIGlmIChydW1wIDwgMTYpIHtcbiAgICAgIHJ1bXAgPSBuZXcgQnVmZmVyKHJ1bXApXG4gICAgICBydW1wLmZpbGwoMClcbiAgICAgIHRoaXMuX2doYXNoLnVwZGF0ZShydW1wKVxuICAgIH1cbiAgfVxuICB0aGlzLl9jYWxsZWQgPSB0cnVlXG4gIHZhciBvdXQgPSB0aGlzLl9tb2RlLmVuY3J5cHQodGhpcywgY2h1bmspXG4gIGlmICh0aGlzLl9kZWNyeXB0KSB7XG4gICAgdGhpcy5fZ2hhc2gudXBkYXRlKGNodW5rKVxuICB9IGVsc2Uge1xuICAgIHRoaXMuX2doYXNoLnVwZGF0ZShvdXQpXG4gIH1cbiAgdGhpcy5fbGVuICs9IGNodW5rLmxlbmd0aFxuICByZXR1cm4gb3V0XG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuX2RlY3J5cHQgJiYgIXRoaXMuX2F1dGhUYWcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIHN0YXRlIG9yIHVuYWJsZSB0byBhdXRoZW50aWNhdGUgZGF0YScpXG4gIH1cbiAgdmFyIHRhZyA9IHhvcih0aGlzLl9naGFzaC5maW5hbCh0aGlzLl9hbGVuICogOCwgdGhpcy5fbGVuICogOCksIHRoaXMuX2NpcGhlci5lbmNyeXB0QmxvY2sodGhpcy5fZmluSUQpKVxuICBpZiAodGhpcy5fZGVjcnlwdCkge1xuICAgIGlmICh4b3JUZXN0KHRhZywgdGhpcy5fYXV0aFRhZykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgc3RhdGUgb3IgdW5hYmxlIHRvIGF1dGhlbnRpY2F0ZSBkYXRhJylcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fYXV0aFRhZyA9IHRhZ1xuICB9XG4gIHRoaXMuX2NpcGhlci5zY3J1YigpXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiBnZXRBdXRoVGFnICgpIHtcbiAgaWYgKCF0aGlzLl9kZWNyeXB0ICYmIEJ1ZmZlci5pc0J1ZmZlcih0aGlzLl9hdXRoVGFnKSkge1xuICAgIHJldHVybiB0aGlzLl9hdXRoVGFnXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG4gIH1cbn1cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuc2V0QXV0aFRhZyA9IGZ1bmN0aW9uIHNldEF1dGhUYWcgKHRhZykge1xuICBpZiAodGhpcy5fZGVjcnlwdCkge1xuICAgIHRoaXMuX2F1dGhUYWcgPSB0YWdcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0F0dGVtcHRpbmcgdG8gc2V0IGF1dGggdGFnIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbiAgfVxufVxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5zZXRBQUQgPSBmdW5jdGlvbiBzZXRBQUQgKGJ1Zikge1xuICBpZiAoIXRoaXMuX2NhbGxlZCkge1xuICAgIHRoaXMuX2doYXNoLnVwZGF0ZShidWYpXG4gICAgdGhpcy5fYWxlbiArPSBidWYubGVuZ3RoXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIHNldCBBQUQgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxuICB9XG59XG5mdW5jdGlvbiB4b3JUZXN0IChhLCBiKSB7XG4gIHZhciBvdXQgPSAwXG4gIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHtcbiAgICBvdXQrK1xuICB9XG4gIHZhciBsZW4gPSBNYXRoLm1pbihhLmxlbmd0aCwgYi5sZW5ndGgpXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dCArPSAoYVtpXSBeIGJbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgbW9kZXMgPSByZXF1aXJlKCcuL21vZGVzJylcbnZhciBTdHJlYW1DaXBoZXIgPSByZXF1aXJlKCcuL3N0cmVhbUNpcGhlcicpXG52YXIgQXV0aENpcGhlciA9IHJlcXVpcmUoJy4vYXV0aENpcGhlcicpXG52YXIgZWJ0ayA9IHJlcXVpcmUoJ2V2cF9ieXRlc3Rva2V5JylcblxuaW5oZXJpdHMoRGVjaXBoZXIsIFRyYW5zZm9ybSlcbmZ1bmN0aW9uIERlY2lwaGVyIChtb2RlLCBrZXksIGl2KSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBEZWNpcGhlcikpIHtcbiAgICByZXR1cm4gbmV3IERlY2lwaGVyKG1vZGUsIGtleSwgaXYpXG4gIH1cbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5fY2FjaGUgPSBuZXcgU3BsaXR0ZXIoKVxuICB0aGlzLl9sYXN0ID0gdm9pZCAwXG4gIHRoaXMuX2NpcGhlciA9IG5ldyBhZXMuQUVTKGtleSlcbiAgdGhpcy5fcHJldiA9IG5ldyBCdWZmZXIoaXYubGVuZ3RoKVxuICBpdi5jb3B5KHRoaXMuX3ByZXYpXG4gIHRoaXMuX21vZGUgPSBtb2RlXG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gdHJ1ZVxufVxuRGVjaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB0aGlzLl9jYWNoZS5hZGQoZGF0YSlcbiAgdmFyIGNodW5rXG4gIHZhciB0aGluZ1xuICB2YXIgb3V0ID0gW11cbiAgd2hpbGUgKChjaHVuayA9IHRoaXMuX2NhY2hlLmdldCh0aGlzLl9hdXRvcGFkZGluZykpKSB7XG4gICAgdGhpbmcgPSB0aGlzLl9tb2RlLmRlY3J5cHQodGhpcywgY2h1bmspXG4gICAgb3V0LnB1c2godGhpbmcpXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5jb25jYXQob3V0KVxufVxuRGVjaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNodW5rID0gdGhpcy5fY2FjaGUuZmx1c2goKVxuICBpZiAodGhpcy5fYXV0b3BhZGRpbmcpIHtcbiAgICByZXR1cm4gdW5wYWQodGhpcy5fbW9kZS5kZWNyeXB0KHRoaXMsIGNodW5rKSlcbiAgfSBlbHNlIGlmIChjaHVuaykge1xuICAgIHRocm93IG5ldyBFcnJvcignZGF0YSBub3QgbXVsdGlwbGUgb2YgYmxvY2sgbGVuZ3RoJylcbiAgfVxufVxuRGVjaXBoZXIucHJvdG90eXBlLnNldEF1dG9QYWRkaW5nID0gZnVuY3Rpb24gKHNldFRvKSB7XG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gISFzZXRUb1xuICByZXR1cm4gdGhpc1xufVxuZnVuY3Rpb24gU3BsaXR0ZXIgKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3BsaXR0ZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBTcGxpdHRlcigpXG4gIH1cbiAgdGhpcy5jYWNoZSA9IG5ldyBCdWZmZXIoJycpXG59XG5TcGxpdHRlci5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIGRhdGFdKVxufVxuXG5TcGxpdHRlci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGF1dG9QYWRkaW5nKSB7XG4gIHZhciBvdXRcbiAgaWYgKGF1dG9QYWRkaW5nKSB7XG4gICAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoID4gMTYpIHtcbiAgICAgIG91dCA9IHRoaXMuY2FjaGUuc2xpY2UoMCwgMTYpXG4gICAgICB0aGlzLmNhY2hlID0gdGhpcy5jYWNoZS5zbGljZSgxNilcbiAgICAgIHJldHVybiBvdXRcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoID49IDE2KSB7XG4gICAgICBvdXQgPSB0aGlzLmNhY2hlLnNsaWNlKDAsIDE2KVxuICAgICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgICByZXR1cm4gb3V0XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsXG59XG5TcGxpdHRlci5wcm90b3R5cGUuZmx1c2ggPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmNhY2hlLmxlbmd0aCkge1xuICAgIHJldHVybiB0aGlzLmNhY2hlXG4gIH1cbn1cbmZ1bmN0aW9uIHVucGFkIChsYXN0KSB7XG4gIHZhciBwYWRkZWQgPSBsYXN0WzE1XVxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBwYWRkZWQpIHtcbiAgICBpZiAobGFzdFsoaSArICgxNiAtIHBhZGRlZCkpXSAhPT0gcGFkZGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VuYWJsZSB0byBkZWNyeXB0IGRhdGEnKVxuICAgIH1cbiAgfVxuICBpZiAocGFkZGVkID09PSAxNikge1xuICAgIHJldHVyblxuICB9XG4gIHJldHVybiBsYXN0LnNsaWNlKDAsIDE2IC0gcGFkZGVkKVxufVxuXG52YXIgbW9kZWxpc3QgPSB7XG4gIEVDQjogcmVxdWlyZSgnLi9tb2Rlcy9lY2InKSxcbiAgQ0JDOiByZXF1aXJlKCcuL21vZGVzL2NiYycpLFxuICBDRkI6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiJyksXG4gIENGQjg6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiOCcpLFxuICBDRkIxOiByZXF1aXJlKCcuL21vZGVzL2NmYjEnKSxcbiAgT0ZCOiByZXF1aXJlKCcuL21vZGVzL29mYicpLFxuICBDVFI6IHJlcXVpcmUoJy4vbW9kZXMvY3RyJyksXG4gIEdDTTogcmVxdWlyZSgnLi9tb2Rlcy9jdHInKVxufVxuXG5mdW5jdGlvbiBjcmVhdGVEZWNpcGhlcml2IChzdWl0ZSwgcGFzc3dvcmQsIGl2KSB7XG4gIHZhciBjb25maWcgPSBtb2Rlc1tzdWl0ZS50b0xvd2VyQ2FzZSgpXVxuICBpZiAoIWNvbmZpZykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgaWYgKHR5cGVvZiBpdiA9PT0gJ3N0cmluZycpIHtcbiAgICBpdiA9IG5ldyBCdWZmZXIoaXYpXG4gIH1cbiAgaWYgKHR5cGVvZiBwYXNzd29yZCA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXNzd29yZCA9IG5ldyBCdWZmZXIocGFzc3dvcmQpXG4gIH1cbiAgaWYgKHBhc3N3b3JkLmxlbmd0aCAhPT0gY29uZmlnLmtleSAvIDgpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGtleSBsZW5ndGggJyArIHBhc3N3b3JkLmxlbmd0aClcbiAgfVxuICBpZiAoaXYubGVuZ3RoICE9PSBjb25maWcuaXYpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGl2IGxlbmd0aCAnICsgaXYubGVuZ3RoKVxuICB9XG4gIGlmIChjb25maWcudHlwZSA9PT0gJ3N0cmVhbScpIHtcbiAgICByZXR1cm4gbmV3IFN0cmVhbUNpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdiwgdHJ1ZSlcbiAgfSBlbHNlIGlmIChjb25maWcudHlwZSA9PT0gJ2F1dGgnKSB7XG4gICAgcmV0dXJuIG5ldyBBdXRoQ2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2LCB0cnVlKVxuICB9XG4gIHJldHVybiBuZXcgRGVjaXBoZXIobW9kZWxpc3RbY29uZmlnLm1vZGVdLCBwYXNzd29yZCwgaXYpXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZURlY2lwaGVyIChzdWl0ZSwgcGFzc3dvcmQpIHtcbiAgdmFyIGNvbmZpZyA9IG1vZGVzW3N1aXRlLnRvTG93ZXJDYXNlKCldXG4gIGlmICghY29uZmlnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBzdWl0ZSB0eXBlJylcbiAgfVxuICB2YXIga2V5cyA9IGVidGsocGFzc3dvcmQsIGZhbHNlLCBjb25maWcua2V5LCBjb25maWcuaXYpXG4gIHJldHVybiBjcmVhdGVEZWNpcGhlcml2KHN1aXRlLCBrZXlzLmtleSwga2V5cy5pdilcbn1cbmV4cG9ydHMuY3JlYXRlRGVjaXBoZXIgPSBjcmVhdGVEZWNpcGhlclxuZXhwb3J0cy5jcmVhdGVEZWNpcGhlcml2ID0gY3JlYXRlRGVjaXBoZXJpdlxuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgbW9kZXMgPSByZXF1aXJlKCcuL21vZGVzJylcbnZhciBlYnRrID0gcmVxdWlyZSgnZXZwX2J5dGVzdG9rZXknKVxudmFyIFN0cmVhbUNpcGhlciA9IHJlcXVpcmUoJy4vc3RyZWFtQ2lwaGVyJylcbnZhciBBdXRoQ2lwaGVyID0gcmVxdWlyZSgnLi9hdXRoQ2lwaGVyJylcbmluaGVyaXRzKENpcGhlciwgVHJhbnNmb3JtKVxuZnVuY3Rpb24gQ2lwaGVyIChtb2RlLCBrZXksIGl2KSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBDaXBoZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBDaXBoZXIobW9kZSwga2V5LCBpdilcbiAgfVxuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuICB0aGlzLl9jYWNoZSA9IG5ldyBTcGxpdHRlcigpXG4gIHRoaXMuX2NpcGhlciA9IG5ldyBhZXMuQUVTKGtleSlcbiAgdGhpcy5fcHJldiA9IG5ldyBCdWZmZXIoaXYubGVuZ3RoKVxuICBpdi5jb3B5KHRoaXMuX3ByZXYpXG4gIHRoaXMuX21vZGUgPSBtb2RlXG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gdHJ1ZVxufVxuQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5fY2FjaGUuYWRkKGRhdGEpXG4gIHZhciBjaHVua1xuICB2YXIgdGhpbmdcbiAgdmFyIG91dCA9IFtdXG4gIHdoaWxlICgoY2h1bmsgPSB0aGlzLl9jYWNoZS5nZXQoKSkpIHtcbiAgICB0aGluZyA9IHRoaXMuX21vZGUuZW5jcnlwdCh0aGlzLCBjaHVuaylcbiAgICBvdXQucHVzaCh0aGluZylcbiAgfVxuICByZXR1cm4gQnVmZmVyLmNvbmNhdChvdXQpXG59XG5DaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNodW5rID0gdGhpcy5fY2FjaGUuZmx1c2goKVxuICBpZiAodGhpcy5fYXV0b3BhZGRpbmcpIHtcbiAgICBjaHVuayA9IHRoaXMuX21vZGUuZW5jcnlwdCh0aGlzLCBjaHVuaylcbiAgICB0aGlzLl9jaXBoZXIuc2NydWIoKVxuICAgIHJldHVybiBjaHVua1xuICB9IGVsc2UgaWYgKGNodW5rLnRvU3RyaW5nKCdoZXgnKSAhPT0gJzEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwJykge1xuICAgIHRoaXMuX2NpcGhlci5zY3J1YigpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhIG5vdCBtdWx0aXBsZSBvZiBibG9jayBsZW5ndGgnKVxuICB9XG59XG5DaXBoZXIucHJvdG90eXBlLnNldEF1dG9QYWRkaW5nID0gZnVuY3Rpb24gKHNldFRvKSB7XG4gIHRoaXMuX2F1dG9wYWRkaW5nID0gISFzZXRUb1xuICByZXR1cm4gdGhpc1xufVxuXG5mdW5jdGlvbiBTcGxpdHRlciAoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTcGxpdHRlcikpIHtcbiAgICByZXR1cm4gbmV3IFNwbGl0dGVyKClcbiAgfVxuICB0aGlzLmNhY2hlID0gbmV3IEJ1ZmZlcignJylcbn1cblNwbGl0dGVyLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB0aGlzLmNhY2hlID0gQnVmZmVyLmNvbmNhdChbdGhpcy5jYWNoZSwgZGF0YV0pXG59XG5cblNwbGl0dGVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmNhY2hlLmxlbmd0aCA+IDE1KSB7XG4gICAgdmFyIG91dCA9IHRoaXMuY2FjaGUuc2xpY2UoMCwgMTYpXG4gICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgcmV0dXJuIG91dFxuICB9XG4gIHJldHVybiBudWxsXG59XG5TcGxpdHRlci5wcm90b3R5cGUuZmx1c2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBsZW4gPSAxNiAtIHRoaXMuY2FjaGUubGVuZ3RoXG4gIHZhciBwYWRCdWZmID0gbmV3IEJ1ZmZlcihsZW4pXG5cbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgcGFkQnVmZi53cml0ZVVJbnQ4KGxlbiwgaSlcbiAgfVxuICB2YXIgb3V0ID0gQnVmZmVyLmNvbmNhdChbdGhpcy5jYWNoZSwgcGFkQnVmZl0pXG4gIHJldHVybiBvdXRcbn1cbnZhciBtb2RlbGlzdCA9IHtcbiAgRUNCOiByZXF1aXJlKCcuL21vZGVzL2VjYicpLFxuICBDQkM6IHJlcXVpcmUoJy4vbW9kZXMvY2JjJyksXG4gIENGQjogcmVxdWlyZSgnLi9tb2Rlcy9jZmInKSxcbiAgQ0ZCODogcmVxdWlyZSgnLi9tb2Rlcy9jZmI4JyksXG4gIENGQjE6IHJlcXVpcmUoJy4vbW9kZXMvY2ZiMScpLFxuICBPRkI6IHJlcXVpcmUoJy4vbW9kZXMvb2ZiJyksXG4gIENUUjogcmVxdWlyZSgnLi9tb2Rlcy9jdHInKSxcbiAgR0NNOiByZXF1aXJlKCcuL21vZGVzL2N0cicpXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNpcGhlcml2IChzdWl0ZSwgcGFzc3dvcmQsIGl2KSB7XG4gIHZhciBjb25maWcgPSBtb2Rlc1tzdWl0ZS50b0xvd2VyQ2FzZSgpXVxuICBpZiAoIWNvbmZpZykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cbiAgaWYgKHR5cGVvZiBpdiA9PT0gJ3N0cmluZycpIHtcbiAgICBpdiA9IG5ldyBCdWZmZXIoaXYpXG4gIH1cbiAgaWYgKHR5cGVvZiBwYXNzd29yZCA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXNzd29yZCA9IG5ldyBCdWZmZXIocGFzc3dvcmQpXG4gIH1cbiAgaWYgKHBhc3N3b3JkLmxlbmd0aCAhPT0gY29uZmlnLmtleSAvIDgpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGtleSBsZW5ndGggJyArIHBhc3N3b3JkLmxlbmd0aClcbiAgfVxuICBpZiAoaXYubGVuZ3RoICE9PSBjb25maWcuaXYpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGl2IGxlbmd0aCAnICsgaXYubGVuZ3RoKVxuICB9XG4gIGlmIChjb25maWcudHlwZSA9PT0gJ3N0cmVhbScpIHtcbiAgICByZXR1cm4gbmV3IFN0cmVhbUNpcGhlcihtb2RlbGlzdFtjb25maWcubW9kZV0sIHBhc3N3b3JkLCBpdilcbiAgfSBlbHNlIGlmIChjb25maWcudHlwZSA9PT0gJ2F1dGgnKSB7XG4gICAgcmV0dXJuIG5ldyBBdXRoQ2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2KVxuICB9XG4gIHJldHVybiBuZXcgQ2lwaGVyKG1vZGVsaXN0W2NvbmZpZy5tb2RlXSwgcGFzc3dvcmQsIGl2KVxufVxuZnVuY3Rpb24gY3JlYXRlQ2lwaGVyIChzdWl0ZSwgcGFzc3dvcmQpIHtcbiAgdmFyIGNvbmZpZyA9IG1vZGVzW3N1aXRlLnRvTG93ZXJDYXNlKCldXG4gIGlmICghY29uZmlnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBzdWl0ZSB0eXBlJylcbiAgfVxuICB2YXIga2V5cyA9IGVidGsocGFzc3dvcmQsIGZhbHNlLCBjb25maWcua2V5LCBjb25maWcuaXYpXG4gIHJldHVybiBjcmVhdGVDaXBoZXJpdihzdWl0ZSwga2V5cy5rZXksIGtleXMuaXYpXG59XG5cbmV4cG9ydHMuY3JlYXRlQ2lwaGVyaXYgPSBjcmVhdGVDaXBoZXJpdlxuZXhwb3J0cy5jcmVhdGVDaXBoZXIgPSBjcmVhdGVDaXBoZXJcbiIsInZhciB6ZXJvcyA9IG5ldyBCdWZmZXIoMTYpXG56ZXJvcy5maWxsKDApXG5tb2R1bGUuZXhwb3J0cyA9IEdIQVNIXG5mdW5jdGlvbiBHSEFTSCAoa2V5KSB7XG4gIHRoaXMuaCA9IGtleVxuICB0aGlzLnN0YXRlID0gbmV3IEJ1ZmZlcigxNilcbiAgdGhpcy5zdGF0ZS5maWxsKDApXG4gIHRoaXMuY2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxufVxuLy8gZnJvbSBodHRwOi8vYml0d2lzZXNoaWZ0bGVmdC5naXRodWIuaW8vc2pjbC9kb2Mvc3ltYm9scy9zcmMvY29yZV9nY20uanMuaHRtbFxuLy8gYnkgSnVobyBWw6Row6QtSGVydHR1YVxuR0hBU0gucHJvdG90eXBlLmdoYXNoID0gZnVuY3Rpb24gKGJsb2NrKSB7XG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGJsb2NrLmxlbmd0aCkge1xuICAgIHRoaXMuc3RhdGVbaV0gXj0gYmxvY2tbaV1cbiAgfVxuICB0aGlzLl9tdWx0aXBseSgpXG59XG5cbkdIQVNILnByb3RvdHlwZS5fbXVsdGlwbHkgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBWaSA9IHRvQXJyYXkodGhpcy5oKVxuICB2YXIgWmkgPSBbMCwgMCwgMCwgMF1cbiAgdmFyIGosIHhpLCBsc2JfVmlcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgMTI4KSB7XG4gICAgeGkgPSAodGhpcy5zdGF0ZVt+fihpIC8gOCldICYgKDEgPDwgKDcgLSBpICUgOCkpKSAhPT0gMFxuICAgIGlmICh4aSkge1xuICAgICAgLy8gWl9pKzEgPSBaX2kgXiBWX2lcbiAgICAgIFppID0geG9yKFppLCBWaSlcbiAgICB9XG5cbiAgICAvLyBTdG9yZSB0aGUgdmFsdWUgb2YgTFNCKFZfaSlcbiAgICBsc2JfVmkgPSAoVmlbM10gJiAxKSAhPT0gMFxuXG4gICAgLy8gVl9pKzEgPSBWX2kgPj4gMVxuICAgIGZvciAoaiA9IDM7IGogPiAwOyBqLS0pIHtcbiAgICAgIFZpW2pdID0gKFZpW2pdID4+PiAxKSB8ICgoVmlbaiAtIDFdICYgMSkgPDwgMzEpXG4gICAgfVxuICAgIFZpWzBdID0gVmlbMF0gPj4+IDFcblxuICAgIC8vIElmIExTQihWX2kpIGlzIDEsIFZfaSsxID0gKFZfaSA+PiAxKSBeIFJcbiAgICBpZiAobHNiX1ZpKSB7XG4gICAgICBWaVswXSA9IFZpWzBdIF4gKDB4ZTEgPDwgMjQpXG4gICAgfVxuICB9XG4gIHRoaXMuc3RhdGUgPSBmcm9tQXJyYXkoWmkpXG59XG5HSEFTSC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGJ1Zikge1xuICB0aGlzLmNhY2hlID0gQnVmZmVyLmNvbmNhdChbdGhpcy5jYWNoZSwgYnVmXSlcbiAgdmFyIGNodW5rXG4gIHdoaWxlICh0aGlzLmNhY2hlLmxlbmd0aCA+PSAxNikge1xuICAgIGNodW5rID0gdGhpcy5jYWNoZS5zbGljZSgwLCAxNilcbiAgICB0aGlzLmNhY2hlID0gdGhpcy5jYWNoZS5zbGljZSgxNilcbiAgICB0aGlzLmdoYXNoKGNodW5rKVxuICB9XG59XG5HSEFTSC5wcm90b3R5cGUuZmluYWwgPSBmdW5jdGlvbiAoYWJsLCBibCkge1xuICBpZiAodGhpcy5jYWNoZS5sZW5ndGgpIHtcbiAgICB0aGlzLmdoYXNoKEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIHplcm9zXSwgMTYpKVxuICB9XG4gIHRoaXMuZ2hhc2goZnJvbUFycmF5KFtcbiAgICAwLCBhYmwsXG4gICAgMCwgYmxcbiAgXSkpXG4gIHJldHVybiB0aGlzLnN0YXRlXG59XG5cbmZ1bmN0aW9uIHRvQXJyYXkgKGJ1Zikge1xuICByZXR1cm4gW1xuICAgIGJ1Zi5yZWFkVUludDMyQkUoMCksXG4gICAgYnVmLnJlYWRVSW50MzJCRSg0KSxcbiAgICBidWYucmVhZFVJbnQzMkJFKDgpLFxuICAgIGJ1Zi5yZWFkVUludDMyQkUoMTIpXG4gIF1cbn1cbmZ1bmN0aW9uIGZyb21BcnJheSAob3V0KSB7XG4gIG91dCA9IG91dC5tYXAoZml4dXBfdWludDMyKVxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcigxNilcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzBdLCAwKVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMV0sIDQpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsyXSwgOClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzNdLCAxMilcbiAgcmV0dXJuIGJ1ZlxufVxudmFyIHVpbnRfbWF4ID0gTWF0aC5wb3coMiwgMzIpXG5mdW5jdGlvbiBmaXh1cF91aW50MzIgKHgpIHtcbiAgdmFyIHJldCwgeF9wb3NcbiAgcmV0ID0geCA+IHVpbnRfbWF4IHx8IHggPCAwID8gKHhfcG9zID0gTWF0aC5hYnMoeCkgJSB1aW50X21heCwgeCA8IDAgPyB1aW50X21heCAtIHhfcG9zIDogeF9wb3MpIDogeFxuICByZXR1cm4gcmV0XG59XG5mdW5jdGlvbiB4b3IgKGEsIGIpIHtcbiAgcmV0dXJuIFtcbiAgICBhWzBdIF4gYlswXSxcbiAgICBhWzFdIF4gYlsxXSxcbiAgICBhWzJdIF4gYlsyXSxcbiAgICBhWzNdIF4gYlszXVxuICBdXG59XG4iLCJ2YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG5cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBkYXRhLCBkZWNyeXB0KSB7XG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKCcnKVxuICB2YXIgbGVuXG5cbiAgd2hpbGUgKGRhdGEubGVuZ3RoKSB7XG4gICAgaWYgKHNlbGYuX2NhY2hlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gICAgICBzZWxmLl9wcmV2ID0gbmV3IEJ1ZmZlcignJylcbiAgICB9XG5cbiAgICBpZiAoc2VsZi5fY2FjaGUubGVuZ3RoIDw9IGRhdGEubGVuZ3RoKSB7XG4gICAgICBsZW4gPSBzZWxmLl9jYWNoZS5sZW5ndGhcbiAgICAgIG91dCA9IEJ1ZmZlci5jb25jYXQoW291dCwgZW5jcnlwdFN0YXJ0KHNlbGYsIGRhdGEuc2xpY2UoMCwgbGVuKSwgZGVjcnlwdCldKVxuICAgICAgZGF0YSA9IGRhdGEuc2xpY2UobGVuKVxuICAgIH0gZWxzZSB7XG4gICAgICBvdXQgPSBCdWZmZXIuY29uY2F0KFtvdXQsIGVuY3J5cHRTdGFydChzZWxmLCBkYXRhLCBkZWNyeXB0KV0pXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvdXRcbn1cbmZ1bmN0aW9uIGVuY3J5cHRTdGFydCAoc2VsZiwgZGF0YSwgZGVjcnlwdCkge1xuICB2YXIgbGVuID0gZGF0YS5sZW5ndGhcbiAgdmFyIG91dCA9IHhvcihkYXRhLCBzZWxmLl9jYWNoZSlcbiAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jYWNoZS5zbGljZShsZW4pXG4gIHNlbGYuX3ByZXYgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9wcmV2LCBkZWNyeXB0ID8gZGF0YSA6IG91dF0pXG4gIHJldHVybiBvdXRcbn1cbiIsImZ1bmN0aW9uIGVuY3J5cHRCeXRlIChzZWxmLCBieXRlUGFyYW0sIGRlY3J5cHQpIHtcbiAgdmFyIHBhZFxuICB2YXIgaSA9IC0xXG4gIHZhciBsZW4gPSA4XG4gIHZhciBvdXQgPSAwXG4gIHZhciBiaXQsIHZhbHVlXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBwYWQgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gICAgYml0ID0gKGJ5dGVQYXJhbSAmICgxIDw8ICg3IC0gaSkpKSA/IDB4ODAgOiAwXG4gICAgdmFsdWUgPSBwYWRbMF0gXiBiaXRcbiAgICBvdXQgKz0gKCh2YWx1ZSAmIDB4ODApID4+IChpICUgOCkpXG4gICAgc2VsZi5fcHJldiA9IHNoaWZ0SW4oc2VsZi5fcHJldiwgZGVjcnlwdCA/IGJpdCA6IHZhbHVlKVxuICB9XG4gIHJldHVybiBvdXRcbn1cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBjaHVuaywgZGVjcnlwdCkge1xuICB2YXIgbGVuID0gY2h1bmsubGVuZ3RoXG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKGxlbilcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgb3V0W2ldID0gZW5jcnlwdEJ5dGUoc2VsZiwgY2h1bmtbaV0sIGRlY3J5cHQpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuZnVuY3Rpb24gc2hpZnRJbiAoYnVmZmVyLCB2YWx1ZSkge1xuICB2YXIgbGVuID0gYnVmZmVyLmxlbmd0aFxuICB2YXIgaSA9IC0xXG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKGJ1ZmZlci5sZW5ndGgpXG4gIGJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoW2J1ZmZlciwgbmV3IEJ1ZmZlcihbdmFsdWVdKV0pXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBvdXRbaV0gPSBidWZmZXJbaV0gPDwgMSB8IGJ1ZmZlcltpICsgMV0gPj4gKDcpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwiZnVuY3Rpb24gZW5jcnlwdEJ5dGUgKHNlbGYsIGJ5dGVQYXJhbSwgZGVjcnlwdCkge1xuICB2YXIgcGFkID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhzZWxmLl9wcmV2KVxuICB2YXIgb3V0ID0gcGFkWzBdIF4gYnl0ZVBhcmFtXG4gIHNlbGYuX3ByZXYgPSBCdWZmZXIuY29uY2F0KFtzZWxmLl9wcmV2LnNsaWNlKDEpLCBuZXcgQnVmZmVyKFtkZWNyeXB0ID8gYnl0ZVBhcmFtIDogb3V0XSldKVxuICByZXR1cm4gb3V0XG59XG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgY2h1bmssIGRlY3J5cHQpIHtcbiAgdmFyIGxlbiA9IGNodW5rLmxlbmd0aFxuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihsZW4pXG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dFtpXSA9IGVuY3J5cHRCeXRlKHNlbGYsIGNodW5rW2ldLCBkZWNyeXB0KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsInZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcblxuZnVuY3Rpb24gaW5jcjMyIChpdikge1xuICB2YXIgbGVuID0gaXYubGVuZ3RoXG4gIHZhciBpdGVtXG4gIHdoaWxlIChsZW4tLSkge1xuICAgIGl0ZW0gPSBpdi5yZWFkVUludDgobGVuKVxuICAgIGlmIChpdGVtID09PSAyNTUpIHtcbiAgICAgIGl2LndyaXRlVUludDgoMCwgbGVuKVxuICAgIH0gZWxzZSB7XG4gICAgICBpdGVtKytcbiAgICAgIGl2LndyaXRlVUludDgoaXRlbSwgbGVuKVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0QmxvY2sgKHNlbGYpIHtcbiAgdmFyIG91dCA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soc2VsZi5fcHJldilcbiAgaW5jcjMyKHNlbGYuX3ByZXYpXG4gIHJldHVybiBvdXRcbn1cblxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGNodW5rKSB7XG4gIHdoaWxlIChzZWxmLl9jYWNoZS5sZW5ndGggPCBjaHVuay5sZW5ndGgpIHtcbiAgICBzZWxmLl9jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3NlbGYuX2NhY2hlLCBnZXRCbG9jayhzZWxmKV0pXG4gIH1cbiAgdmFyIHBhZCA9IHNlbGYuX2NhY2hlLnNsaWNlKDAsIGNodW5rLmxlbmd0aClcbiAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jYWNoZS5zbGljZShjaHVuay5sZW5ndGgpXG4gIHJldHVybiB4b3IoY2h1bmssIHBhZClcbn1cbiIsInZhciB4b3IgPSByZXF1aXJlKCdidWZmZXIteG9yJylcblxuZnVuY3Rpb24gZ2V0QmxvY2sgKHNlbGYpIHtcbiAgc2VsZi5fcHJldiA9IHNlbGYuX2NpcGhlci5lbmNyeXB0QmxvY2soc2VsZi5fcHJldilcbiAgcmV0dXJuIHNlbGYuX3ByZXZcbn1cblxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGNodW5rKSB7XG4gIHdoaWxlIChzZWxmLl9jYWNoZS5sZW5ndGggPCBjaHVuay5sZW5ndGgpIHtcbiAgICBzZWxmLl9jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3NlbGYuX2NhY2hlLCBnZXRCbG9jayhzZWxmKV0pXG4gIH1cblxuICB2YXIgcGFkID0gc2VsZi5fY2FjaGUuc2xpY2UoMCwgY2h1bmsubGVuZ3RoKVxuICBzZWxmLl9jYWNoZSA9IHNlbGYuX2NhY2hlLnNsaWNlKGNodW5rLmxlbmd0aClcbiAgcmV0dXJuIHhvcihjaHVuaywgcGFkKVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB4b3IgKGEsIGIpIHtcbiAgdmFyIGxlbmd0aCA9IE1hdGgubWluKGEubGVuZ3RoLCBiLmxlbmd0aClcbiAgdmFyIGJ1ZmZlciA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBidWZmZXJbaV0gPSBhW2ldIF4gYltpXVxuICB9XG5cbiAgcmV0dXJuIGJ1ZmZlclxufVxuIiwidmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ3N0cmVhbScpLlRyYW5zZm9ybVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2RlcicpLlN0cmluZ0RlY29kZXJcbm1vZHVsZS5leHBvcnRzID0gQ2lwaGVyQmFzZVxuaW5oZXJpdHMoQ2lwaGVyQmFzZSwgVHJhbnNmb3JtKVxuZnVuY3Rpb24gQ2lwaGVyQmFzZSAoaGFzaE1vZGUpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5oYXNoTW9kZSA9IHR5cGVvZiBoYXNoTW9kZSA9PT0gJ3N0cmluZydcbiAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICB0aGlzW2hhc2hNb2RlXSA9IHRoaXMuX2ZpbmFsT3JEaWdlc3RcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmZpbmFsID0gdGhpcy5fZmluYWxPckRpZ2VzdFxuICB9XG4gIHRoaXMuX2RlY29kZXIgPSBudWxsXG4gIHRoaXMuX2VuY29kaW5nID0gbnVsbFxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGlucHV0RW5jLCBvdXRwdXRFbmMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIGRhdGEgPSBuZXcgQnVmZmVyKGRhdGEsIGlucHV0RW5jKVxuICB9XG4gIHZhciBvdXREYXRhID0gdGhpcy5fdXBkYXRlKGRhdGEpXG4gIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuICBpZiAob3V0cHV0RW5jKSB7XG4gICAgb3V0RGF0YSA9IHRoaXMuX3RvU3RyaW5nKG91dERhdGEsIG91dHB1dEVuYylcbiAgfVxuICByZXR1cm4gb3V0RGF0YVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBdXRvUGFkZGluZyA9IGZ1bmN0aW9uICgpIHt9XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIHNldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEFBRCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gc2V0IGFhZCBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoZGF0YSwgXywgbmV4dCkge1xuICB2YXIgZXJyXG4gIHRyeSB7XG4gICAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZShkYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnB1c2godGhpcy5fdXBkYXRlKGRhdGEpKVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfSBmaW5hbGx5IHtcbiAgICBuZXh0KGVycilcbiAgfVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZsdXNoID0gZnVuY3Rpb24gKGRvbmUpIHtcbiAgdmFyIGVyclxuICB0cnkge1xuICAgIHRoaXMucHVzaCh0aGlzLl9maW5hbCgpKVxuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyID0gZVxuICB9IGZpbmFsbHkge1xuICAgIGRvbmUoZXJyKVxuICB9XG59XG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fZmluYWxPckRpZ2VzdCA9IGZ1bmN0aW9uIChvdXRwdXRFbmMpIHtcbiAgdmFyIG91dERhdGEgPSB0aGlzLl9maW5hbCgpIHx8IG5ldyBCdWZmZXIoJycpXG4gIGlmIChvdXRwdXRFbmMpIHtcbiAgICBvdXREYXRhID0gdGhpcy5fdG9TdHJpbmcob3V0RGF0YSwgb3V0cHV0RW5jLCB0cnVlKVxuICB9XG4gIHJldHVybiBvdXREYXRhXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90b1N0cmluZyA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jLCBmaW5hbCkge1xuICBpZiAoIXRoaXMuX2RlY29kZXIpIHtcbiAgICB0aGlzLl9kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKVxuICAgIHRoaXMuX2VuY29kaW5nID0gZW5jXG4gIH1cbiAgaWYgKHRoaXMuX2VuY29kaW5nICE9PSBlbmMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NhblxcJ3Qgc3dpdGNoIGVuY29kaW5ncycpXG4gIH1cbiAgdmFyIG91dCA9IHRoaXMuX2RlY29kZXIud3JpdGUodmFsdWUpXG4gIGlmIChmaW5hbCkge1xuICAgIG91dCArPSB0aGlzLl9kZWNvZGVyLmVuZCgpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwidmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG5cbmluaGVyaXRzKFN0cmVhbUNpcGhlciwgVHJhbnNmb3JtKVxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW1DaXBoZXJcbmZ1bmN0aW9uIFN0cmVhbUNpcGhlciAobW9kZSwga2V5LCBpdiwgZGVjcnlwdCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3RyZWFtQ2lwaGVyKSkge1xuICAgIHJldHVybiBuZXcgU3RyZWFtQ2lwaGVyKG1vZGUsIGtleSwgaXYpXG4gIH1cbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5fY2lwaGVyID0gbmV3IGFlcy5BRVMoa2V5KVxuICB0aGlzLl9wcmV2ID0gbmV3IEJ1ZmZlcihpdi5sZW5ndGgpXG4gIHRoaXMuX2NhY2hlID0gbmV3IEJ1ZmZlcignJylcbiAgdGhpcy5fc2VjQ2FjaGUgPSBuZXcgQnVmZmVyKCcnKVxuICB0aGlzLl9kZWNyeXB0ID0gZGVjcnlwdFxuICBpdi5jb3B5KHRoaXMuX3ByZXYpXG4gIHRoaXMuX21vZGUgPSBtb2RlXG59XG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgcmV0dXJuIHRoaXMuX21vZGUuZW5jcnlwdCh0aGlzLCBjaHVuaywgdGhpcy5fZGVjcnlwdClcbn1cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9jaXBoZXIuc2NydWIoKVxufVxuIiwidmFyIG1kNSA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoL21kNScpXG5tb2R1bGUuZXhwb3J0cyA9IEVWUF9CeXRlc1RvS2V5XG5mdW5jdGlvbiBFVlBfQnl0ZXNUb0tleSAocGFzc3dvcmQsIHNhbHQsIGtleUxlbiwgaXZMZW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIocGFzc3dvcmQpKSB7XG4gICAgcGFzc3dvcmQgPSBuZXcgQnVmZmVyKHBhc3N3b3JkLCAnYmluYXJ5JylcbiAgfVxuICBpZiAoc2FsdCAmJiAhQnVmZmVyLmlzQnVmZmVyKHNhbHQpKSB7XG4gICAgc2FsdCA9IG5ldyBCdWZmZXIoc2FsdCwgJ2JpbmFyeScpXG4gIH1cbiAga2V5TGVuID0ga2V5TGVuIC8gOFxuICBpdkxlbiA9IGl2TGVuIHx8IDBcbiAgdmFyIGtpID0gMFxuICB2YXIgaWkgPSAwXG4gIHZhciBrZXkgPSBuZXcgQnVmZmVyKGtleUxlbilcbiAgdmFyIGl2ID0gbmV3IEJ1ZmZlcihpdkxlbilcbiAgdmFyIGFkZG1kID0gMFxuICB2YXIgbWRfYnVmXG4gIHZhciBpXG4gIHZhciBidWZzID0gW11cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAoYWRkbWQrKyA+IDApIHtcbiAgICAgIGJ1ZnMucHVzaChtZF9idWYpXG4gICAgfVxuICAgIGJ1ZnMucHVzaChwYXNzd29yZClcbiAgICBpZiAoc2FsdCkge1xuICAgICAgYnVmcy5wdXNoKHNhbHQpXG4gICAgfVxuICAgIG1kX2J1ZiA9IG1kNShCdWZmZXIuY29uY2F0KGJ1ZnMpKVxuICAgIGJ1ZnMgPSBbXVxuICAgIGkgPSAwXG4gICAgaWYgKGtleUxlbiA+IDApIHtcbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGlmIChrZXlMZW4gPT09IDApIHtcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICAgIGlmIChpID09PSBtZF9idWYubGVuZ3RoKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBrZXlba2krK10gPSBtZF9idWZbaV1cbiAgICAgICAga2V5TGVuLS1cbiAgICAgICAgaSsrXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpdkxlbiA+IDAgJiYgaSAhPT0gbWRfYnVmLmxlbmd0aCkge1xuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgaWYgKGl2TGVuID09PSAwKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaSA9PT0gbWRfYnVmLmxlbmd0aCkge1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgaXZbaWkrK10gPSBtZF9idWZbaV1cbiAgICAgICAgaXZMZW4tLVxuICAgICAgICBpKytcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGtleUxlbiA9PT0gMCAmJiBpdkxlbiA9PT0gMCkge1xuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbiAgZm9yIChpID0gMDsgaSA8IG1kX2J1Zi5sZW5ndGg7IGkrKykge1xuICAgIG1kX2J1ZltpXSA9IDBcbiAgfVxuICByZXR1cm4ge1xuICAgIGtleToga2V5LFxuICAgIGl2OiBpdlxuICB9XG59XG4iLCJ2YXIgcGFyc2VLZXlzID0gcmVxdWlyZSgncGFyc2UtYXNuMScpO1xudmFyIG1nZiA9IHJlcXVpcmUoJy4vbWdmJyk7XG52YXIgeG9yID0gcmVxdWlyZSgnLi94b3InKTtcbnZhciBibiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgY3J0ID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1yc2EnKTtcbnZhciBjcmVhdGVIYXNoID0gcmVxdWlyZSgnY3JlYXRlLWhhc2gnKTtcbnZhciB3aXRoUHVibGljID0gcmVxdWlyZSgnLi93aXRoUHVibGljJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHByaXZhdGVEZWNyeXB0KHByaXZhdGVfa2V5LCBlbmMsIHJldmVyc2UpIHtcbiAgdmFyIHBhZGRpbmc7XG4gIGlmIChwcml2YXRlX2tleS5wYWRkaW5nKSB7XG4gICAgcGFkZGluZyA9IHByaXZhdGVfa2V5LnBhZGRpbmc7XG4gIH0gZWxzZSBpZiAocmV2ZXJzZSkge1xuICAgIHBhZGRpbmcgPSAxO1xuICB9IGVsc2Uge1xuICAgIHBhZGRpbmcgPSA0O1xuICB9XG4gIFxuICB2YXIga2V5ID0gcGFyc2VLZXlzKHByaXZhdGVfa2V5KTtcbiAgdmFyIGsgPSBrZXkubW9kdWx1cy5ieXRlTGVuZ3RoKCk7XG4gIGlmIChlbmMubGVuZ3RoID4gayB8fCBuZXcgYm4oZW5jKS5jbXAoa2V5Lm1vZHVsdXMpID49IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RlY3J5cHRpb24gZXJyb3InKTtcbiAgfVxuICB2YXIgbXNnO1xuICBpZiAocmV2ZXJzZSkge1xuICAgIG1zZyA9IHdpdGhQdWJsaWMobmV3IGJuKGVuYyksIGtleSk7XG4gIH0gZWxzZSB7XG4gICAgbXNnID0gY3J0KGVuYywga2V5KTtcbiAgfVxuICB2YXIgekJ1ZmZlciA9IG5ldyBCdWZmZXIoayAtIG1zZy5sZW5ndGgpO1xuICB6QnVmZmVyLmZpbGwoMCk7XG4gIG1zZyA9IEJ1ZmZlci5jb25jYXQoW3pCdWZmZXIsIG1zZ10sIGspO1xuICBpZiAocGFkZGluZyA9PT0gNCkge1xuICAgIHJldHVybiBvYWVwKGtleSwgbXNnKTtcbiAgfSBlbHNlIGlmIChwYWRkaW5nID09PSAxKSB7XG4gICAgcmV0dXJuIHBrY3MxKGtleSwgbXNnLCByZXZlcnNlKTtcbiAgfSBlbHNlIGlmIChwYWRkaW5nID09PSAzKSB7XG4gICAgcmV0dXJuIG1zZztcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gcGFkZGluZycpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBvYWVwKGtleSwgbXNnKXtcbiAgdmFyIG4gPSBrZXkubW9kdWx1cztcbiAgdmFyIGsgPSBrZXkubW9kdWx1cy5ieXRlTGVuZ3RoKCk7XG4gIHZhciBtTGVuID0gbXNnLmxlbmd0aDtcbiAgdmFyIGlIYXNoID0gY3JlYXRlSGFzaCgnc2hhMScpLnVwZGF0ZShuZXcgQnVmZmVyKCcnKSkuZGlnZXN0KCk7XG4gIHZhciBoTGVuID0gaUhhc2gubGVuZ3RoO1xuICB2YXIgaExlbjIgPSAyICogaExlbjtcbiAgaWYgKG1zZ1swXSAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignZGVjcnlwdGlvbiBlcnJvcicpO1xuICB9XG4gIHZhciBtYXNrZWRTZWVkID0gbXNnLnNsaWNlKDEsIGhMZW4gKyAxKTtcbiAgdmFyIG1hc2tlZERiID0gIG1zZy5zbGljZShoTGVuICsgMSk7XG4gIHZhciBzZWVkID0geG9yKG1hc2tlZFNlZWQsIG1nZihtYXNrZWREYiwgaExlbikpO1xuICB2YXIgZGIgPSB4b3IobWFza2VkRGIsIG1nZihzZWVkLCBrIC0gaExlbiAtIDEpKTtcbiAgaWYgKGNvbXBhcmUoaUhhc2gsIGRiLnNsaWNlKDAsIGhMZW4pKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignZGVjcnlwdGlvbiBlcnJvcicpO1xuICB9XG4gIHZhciBpID0gaExlbjtcbiAgd2hpbGUgKGRiW2ldID09PSAwKSB7XG4gICAgaSsrO1xuICB9XG4gIGlmIChkYltpKytdICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkZWNyeXB0aW9uIGVycm9yJyk7XG4gIH1cbiAgcmV0dXJuIGRiLnNsaWNlKGkpO1xufVxuXG5mdW5jdGlvbiBwa2NzMShrZXksIG1zZywgcmV2ZXJzZSl7XG4gIHZhciBwMSA9IG1zZy5zbGljZSgwLCAyKTtcbiAgdmFyIGkgPSAyO1xuICB2YXIgc3RhdHVzID0gMDtcbiAgd2hpbGUgKG1zZ1tpKytdICE9PSAwKSB7XG4gICAgaWYgKGkgPj0gbXNnLmxlbmd0aCkge1xuICAgICAgc3RhdHVzKys7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgdmFyIHBzID0gbXNnLnNsaWNlKDIsIGkgLSAxKTtcbiAgdmFyIHAyID0gbXNnLnNsaWNlKGkgLSAxLCBpKTtcblxuICBpZiAoKHAxLnRvU3RyaW5nKCdoZXgnKSAhPT0gJzAwMDInICYmICFyZXZlcnNlKSB8fCAocDEudG9TdHJpbmcoJ2hleCcpICE9PSAnMDAwMScgJiYgcmV2ZXJzZSkpe1xuICAgIHN0YXR1cysrO1xuICB9XG4gIGlmIChwcy5sZW5ndGggPCA4KSB7XG4gICAgc3RhdHVzKys7XG4gIH1cbiAgaWYgKHN0YXR1cykge1xuICAgIHRocm93IG5ldyBFcnJvcignZGVjcnlwdGlvbiBlcnJvcicpO1xuICB9XG4gIHJldHVybiAgbXNnLnNsaWNlKGkpO1xufVxuZnVuY3Rpb24gY29tcGFyZShhLCBiKXtcbiAgYSA9IG5ldyBCdWZmZXIoYSk7XG4gIGIgPSBuZXcgQnVmZmVyKGIpO1xuICB2YXIgZGlmID0gMDtcbiAgdmFyIGxlbiA9IGEubGVuZ3RoO1xuICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSB7XG4gICAgZGlmKys7XG4gICAgbGVuID0gTWF0aC5taW4oYS5sZW5ndGgsIGIubGVuZ3RoKTtcbiAgfVxuICB2YXIgaSA9IC0xO1xuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgZGlmICs9IChhW2ldIF4gYltpXSk7XG4gIH1cbiAgcmV0dXJuIGRpZjtcbn0iLCJ2YXIgcGFyc2VLZXlzID0gcmVxdWlyZSgncGFyc2UtYXNuMScpO1xudmFyIHJhbmRvbUJ5dGVzID0gcmVxdWlyZSgncmFuZG9tYnl0ZXMnKTtcbnZhciBjcmVhdGVIYXNoID0gcmVxdWlyZSgnY3JlYXRlLWhhc2gnKTtcbnZhciBtZ2YgPSByZXF1aXJlKCcuL21nZicpO1xudmFyIHhvciA9IHJlcXVpcmUoJy4veG9yJyk7XG52YXIgYm4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIHdpdGhQdWJsaWMgPSByZXF1aXJlKCcuL3dpdGhQdWJsaWMnKTtcbnZhciBjcnQgPSByZXF1aXJlKCdicm93c2VyaWZ5LXJzYScpO1xuXG52YXIgY29uc3RhbnRzID0ge1xuICBSU0FfUEtDUzFfT0FFUF9QQURESU5HOiA0LFxuICBSU0FfUEtDUzFfUEFERElOOiAxLFxuICBSU0FfTk9fUEFERElORzogM1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwdWJsaWNFbmNyeXB0KHB1YmxpY19rZXksIG1zZywgcmV2ZXJzZSkge1xuICB2YXIgcGFkZGluZztcbiAgaWYgKHB1YmxpY19rZXkucGFkZGluZykge1xuICAgIHBhZGRpbmcgPSBwdWJsaWNfa2V5LnBhZGRpbmc7XG4gIH0gZWxzZSBpZiAocmV2ZXJzZSkge1xuICAgIHBhZGRpbmcgPSAxO1xuICB9IGVsc2Uge1xuICAgIHBhZGRpbmcgPSA0O1xuICB9XG4gIHZhciBrZXkgPSBwYXJzZUtleXMocHVibGljX2tleSk7XG4gIHZhciBwYWRkZWRNc2c7XG4gIGlmIChwYWRkaW5nID09PSA0KSB7XG4gICAgcGFkZGVkTXNnID0gb2FlcChrZXksIG1zZyk7XG4gIH0gZWxzZSBpZiAocGFkZGluZyA9PT0gMSkge1xuICAgIHBhZGRlZE1zZyA9IHBrY3MxKGtleSwgbXNnLCByZXZlcnNlKTtcbiAgfSBlbHNlIGlmIChwYWRkaW5nID09PSAzKSB7XG4gICAgcGFkZGVkTXNnID0gbmV3IGJuKG1zZyk7XG4gICAgaWYgKHBhZGRlZE1zZy5jbXAoa2V5Lm1vZHVsdXMpID49IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZGF0YSB0b28gbG9uZyBmb3IgbW9kdWx1cycpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gcGFkZGluZycpO1xuICB9XG4gIGlmIChyZXZlcnNlKSB7XG4gICAgcmV0dXJuIGNydChwYWRkZWRNc2csIGtleSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHdpdGhQdWJsaWMocGFkZGVkTXNnLCBrZXkpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBvYWVwKGtleSwgbXNnKXtcbiAgdmFyIGsgPSBrZXkubW9kdWx1cy5ieXRlTGVuZ3RoKCk7XG4gIHZhciBtTGVuID0gbXNnLmxlbmd0aDtcbiAgdmFyIGlIYXNoID0gY3JlYXRlSGFzaCgnc2hhMScpLnVwZGF0ZShuZXcgQnVmZmVyKCcnKSkuZGlnZXN0KCk7XG4gIHZhciBoTGVuID0gaUhhc2gubGVuZ3RoO1xuICB2YXIgaExlbjIgPSAyICogaExlbjtcbiAgaWYgKG1MZW4gPiBrIC0gaExlbjIgLSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdtZXNzYWdlIHRvbyBsb25nJyk7XG4gIH1cbiAgdmFyIHBzID0gbmV3IEJ1ZmZlcihrIC0gbUxlbiAtIGhMZW4yIC0gMik7XG4gIHBzLmZpbGwoMCk7XG4gIHZhciBkYmxlbiA9IGsgLSBoTGVuIC0gMTtcbiAgdmFyIHNlZWQgPSByYW5kb21CeXRlcyhoTGVuKTtcbiAgdmFyIG1hc2tlZERiID0geG9yKEJ1ZmZlci5jb25jYXQoW2lIYXNoLCBwcywgbmV3IEJ1ZmZlcihbMV0pLCBtc2ddLCBkYmxlbiksIG1nZihzZWVkLCBkYmxlbikpO1xuICB2YXIgbWFza2VkU2VlZCA9IHhvcihzZWVkLCBtZ2YobWFza2VkRGIsIGhMZW4pKTtcbiAgcmV0dXJuIG5ldyBibihCdWZmZXIuY29uY2F0KFtuZXcgQnVmZmVyKFswXSksIG1hc2tlZFNlZWQsIG1hc2tlZERiXSwgaykpO1xufVxuZnVuY3Rpb24gcGtjczEoa2V5LCBtc2csIHJldmVyc2Upe1xuICB2YXIgbUxlbiA9IG1zZy5sZW5ndGg7XG4gIHZhciBrID0ga2V5Lm1vZHVsdXMuYnl0ZUxlbmd0aCgpO1xuICBpZiAobUxlbiA+IGsgLSAxMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignbWVzc2FnZSB0b28gbG9uZycpO1xuICB9XG4gIHZhciBwcztcbiAgaWYgKHJldmVyc2UpIHtcbiAgICBwcyA9IG5ldyBCdWZmZXIoayAtIG1MZW4gLSAzKTtcbiAgICBwcy5maWxsKDB4ZmYpO1xuICB9IGVsc2Uge1xuICAgIHBzID0gbm9uWmVybyhrIC0gbUxlbiAtIDMpO1xuICB9XG4gIHJldHVybiBuZXcgYm4oQnVmZmVyLmNvbmNhdChbbmV3IEJ1ZmZlcihbMCwgcmV2ZXJzZT8xOjJdKSwgcHMsIG5ldyBCdWZmZXIoWzBdKSwgbXNnXSwgaykpO1xufVxuZnVuY3Rpb24gbm9uWmVybyhsZW4sIGNyeXB0bykge1xuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihsZW4pO1xuICB2YXIgaSA9IDA7XG4gIHZhciBjYWNoZSA9IHJhbmRvbUJ5dGVzKGxlbioyKTtcbiAgdmFyIGN1ciA9IDA7XG4gIHZhciBudW07XG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgaWYgKGN1ciA9PT0gY2FjaGUubGVuZ3RoKSB7XG4gICAgICBjYWNoZSA9IHJhbmRvbUJ5dGVzKGxlbioyKTtcbiAgICAgIGN1ciA9IDA7XG4gICAgfVxuICAgIG51bSA9IGNhY2hlW2N1cisrXTtcbiAgICBpZiAobnVtKSB7XG4gICAgICBvdXRbaSsrXSA9IG51bTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG91dDtcbn0iLCJ2YXIgYm4gPSByZXF1aXJlKCdibi5qcycpO1xuZnVuY3Rpb24gd2l0aFB1YmxpYyhwYWRkZWRNc2csIGtleSkge1xuICByZXR1cm4gbmV3IEJ1ZmZlcihwYWRkZWRNc2dcbiAgICAudG9SZWQoYm4ubW9udChrZXkubW9kdWx1cykpXG4gICAgLnJlZFBvdyhuZXcgYm4oa2V5LnB1YmxpY0V4cG9uZW50KSlcbiAgICAuZnJvbVJlZCgpXG4gICAgLnRvQXJyYXkoKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gd2l0aFB1YmxpYzsiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHhvcihhLCBiKSB7XG4gIHZhciBsZW4gPSBhLmxlbmd0aDtcbiAgdmFyIGkgPSAtMTtcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIGFbaV0gXj0gYltpXTtcbiAgfVxuICByZXR1cm4gYVxufTsiLCIndXNlIHN0cmljdCdcblxuZnVuY3Rpb24gb2xkQnJvd3NlciAoKSB7XG4gIHRocm93IG5ldyBFcnJvcignc2VjdXJlIHJhbmRvbSBudW1iZXIgZ2VuZXJhdGlvbiBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgYnJvd3NlclxcbnVzZSBjaHJvbWUsIEZpcmVGb3ggb3IgSW50ZXJuZXQgRXhwbG9yZXIgMTEnKVxufVxuXG52YXIgY3J5cHRvID0gZ2xvYmFsLmNyeXB0byB8fCBnbG9iYWwubXNDcnlwdG9cblxuaWYgKGNyeXB0byAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcmFuZG9tQnl0ZXNcbn0gZWxzZSB7XG4gIG1vZHVsZS5leHBvcnRzID0gb2xkQnJvd3NlclxufVxuXG5mdW5jdGlvbiByYW5kb21CeXRlcyAoc2l6ZSwgY2IpIHtcbiAgLy8gcGhhbnRvbWpzIG5lZWRzIHRvIHRocm93XG4gIGlmIChzaXplID4gNjU1MzYpIHRocm93IG5ldyBFcnJvcigncmVxdWVzdGVkIHRvbyBtYW55IHJhbmRvbSBieXRlcycpXG4gIC8vIGluIGNhc2UgYnJvd3NlcmlmeSAgaXNuJ3QgdXNpbmcgdGhlIFVpbnQ4QXJyYXkgdmVyc2lvblxuICB2YXIgcmF3Qnl0ZXMgPSBuZXcgZ2xvYmFsLlVpbnQ4QXJyYXkoc2l6ZSlcblxuICAvLyBUaGlzIHdpbGwgbm90IHdvcmsgaW4gb2xkZXIgYnJvd3NlcnMuXG4gIC8vIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvd2luZG93LmNyeXB0by5nZXRSYW5kb21WYWx1ZXNcbiAgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhyYXdCeXRlcylcblxuICAvLyBwaGFudG9tanMgZG9lc24ndCBsaWtlIGEgYnVmZmVyIGJlaW5nIHBhc3NlZCBoZXJlXG4gIHZhciBieXRlcyA9IG5ldyBCdWZmZXIocmF3Qnl0ZXMuYnVmZmVyKVxuXG4gIGlmICh0eXBlb2YgY2IgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICBjYihudWxsLCBieXRlcylcbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICB0aGlzLl9ldmVudHMgPSB0aGlzLl9ldmVudHMgfHwge307XG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbkV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbi8vIE9idmlvdXNseSBub3QgYWxsIEVtaXR0ZXJzIHNob3VsZCBiZSBsaW1pdGVkIHRvIDEwLiBUaGlzIGZ1bmN0aW9uIGFsbG93c1xuLy8gdGhhdCB0byBiZSBpbmNyZWFzZWQuIFNldCB0byB6ZXJvIGZvciB1bmxpbWl0ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnNldE1heExpc3RlbmVycyA9IGZ1bmN0aW9uKG4pIHtcbiAgaWYgKCFpc051bWJlcihuKSB8fCBuIDwgMCB8fCBpc05hTihuKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ24gbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSBuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIGVyLCBoYW5kbGVyLCBsZW4sIGFyZ3MsIGksIGxpc3RlbmVycztcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcblxuICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG4gIGlmICh0eXBlID09PSAnZXJyb3InKSB7XG4gICAgaWYgKCF0aGlzLl9ldmVudHMuZXJyb3IgfHxcbiAgICAgICAgKGlzT2JqZWN0KHRoaXMuX2V2ZW50cy5lcnJvcikgJiYgIXRoaXMuX2V2ZW50cy5lcnJvci5sZW5ndGgpKSB7XG4gICAgICBlciA9IGFyZ3VtZW50c1sxXTtcbiAgICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgICAgfVxuICAgICAgdGhyb3cgVHlwZUVycm9yKCdVbmNhdWdodCwgdW5zcGVjaWZpZWQgXCJlcnJvclwiIGV2ZW50LicpO1xuICAgIH1cbiAgfVxuXG4gIGhhbmRsZXIgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgaWYgKGlzVW5kZWZpbmVkKGhhbmRsZXIpKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAoaXNGdW5jdGlvbihoYW5kbGVyKSkge1xuICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgLy8gZmFzdCBjYXNlc1xuICAgICAgY2FzZSAxOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgLy8gc2xvd2VyXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgaGFuZGxlci5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNPYmplY3QoaGFuZGxlcikpIHtcbiAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICBsaXN0ZW5lcnMgPSBoYW5kbGVyLnNsaWNlKCk7XG4gICAgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICB2YXIgbTtcblxuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgLy8gYWRkaW5nIGl0IHRvIHRoZSBsaXN0ZW5lcnMsIGZpcnN0IGVtaXQgXCJuZXdMaXN0ZW5lclwiLlxuICBpZiAodGhpcy5fZXZlbnRzLm5ld0xpc3RlbmVyKVxuICAgIHRoaXMuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgICAgICBpc0Z1bmN0aW9uKGxpc3RlbmVyLmxpc3RlbmVyKSA/XG4gICAgICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIC8vIE9wdGltaXplIHRoZSBjYXNlIG9mIG9uZSBsaXN0ZW5lci4gRG9uJ3QgbmVlZCB0aGUgZXh0cmEgYXJyYXkgb2JqZWN0LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICBlbHNlIGlmIChpc09iamVjdCh0aGlzLl9ldmVudHNbdHlwZV0pKVxuICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0ucHVzaChsaXN0ZW5lcik7XG4gIGVsc2VcbiAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0gPSBbdGhpcy5fZXZlbnRzW3R5cGVdLCBsaXN0ZW5lcl07XG5cbiAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgaWYgKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkgJiYgIXRoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQpIHtcbiAgICBpZiAoIWlzVW5kZWZpbmVkKHRoaXMuX21heExpc3RlbmVycykpIHtcbiAgICAgIG0gPSB0aGlzLl9tYXhMaXN0ZW5lcnM7XG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgICB9XG5cbiAgICBpZiAobSAmJiBtID4gMCAmJiB0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoID4gbSkge1xuICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCA9IHRydWU7XG4gICAgICBjb25zb2xlLmVycm9yKCcobm9kZSkgd2FybmluZzogcG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSAnICtcbiAgICAgICAgICAgICAgICAgICAgJ2xlYWsgZGV0ZWN0ZWQuICVkIGxpc3RlbmVycyBhZGRlZC4gJyArXG4gICAgICAgICAgICAgICAgICAgICdVc2UgZW1pdHRlci5zZXRNYXhMaXN0ZW5lcnMoKSB0byBpbmNyZWFzZSBsaW1pdC4nLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoKTtcbiAgICAgIGlmICh0eXBlb2YgY29uc29sZS50cmFjZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBub3Qgc3VwcG9ydGVkIGluIElFIDEwXG4gICAgICAgIGNvbnNvbGUudHJhY2UoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgdmFyIGZpcmVkID0gZmFsc2U7XG5cbiAgZnVuY3Rpb24gZygpIHtcbiAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGcpO1xuXG4gICAgaWYgKCFmaXJlZCkge1xuICAgICAgZmlyZWQgPSB0cnVlO1xuICAgICAgbGlzdGVuZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cblxuICBnLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHRoaXMub24odHlwZSwgZyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBlbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWZmIHRoZSBsaXN0ZW5lciB3YXMgcmVtb3ZlZFxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBsaXN0LCBwb3NpdGlvbiwgbGVuZ3RoLCBpO1xuXG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIGxpc3QgPSB0aGlzLl9ldmVudHNbdHlwZV07XG4gIGxlbmd0aCA9IGxpc3QubGVuZ3RoO1xuICBwb3NpdGlvbiA9IC0xO1xuXG4gIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fFxuICAgICAgKGlzRnVuY3Rpb24obGlzdC5saXN0ZW5lcikgJiYgbGlzdC5saXN0ZW5lciA9PT0gbGlzdGVuZXIpKSB7XG4gICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcblxuICB9IGVsc2UgaWYgKGlzT2JqZWN0KGxpc3QpKSB7XG4gICAgZm9yIChpID0gbGVuZ3RoOyBpLS0gPiAwOykge1xuICAgICAgaWYgKGxpc3RbaV0gPT09IGxpc3RlbmVyIHx8XG4gICAgICAgICAgKGxpc3RbaV0ubGlzdGVuZXIgJiYgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpKSB7XG4gICAgICAgIHBvc2l0aW9uID0gaTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKGxpc3QubGVuZ3RoID09PSAxKSB7XG4gICAgICBsaXN0Lmxlbmd0aCA9IDA7XG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIH0gZWxzZSB7XG4gICAgICBsaXN0LnNwbGljZShwb3NpdGlvbiwgMSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0ZW5lcik7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIga2V5LCBsaXN0ZW5lcnM7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICBpZiAoIXRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKVxuICAgICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgZWxzZSBpZiAodGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIGZvciAoa2V5IGluIHRoaXMuX2V2ZW50cykge1xuICAgICAgaWYgKGtleSA9PT0gJ3JlbW92ZUxpc3RlbmVyJykgY29udGludWU7XG4gICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgIH1cbiAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygncmVtb3ZlTGlzdGVuZXInKTtcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICBpZiAoaXNGdW5jdGlvbihsaXN0ZW5lcnMpKSB7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICB9IGVsc2UgaWYgKGxpc3RlbmVycykge1xuICAgIC8vIExJRk8gb3JkZXJcbiAgICB3aGlsZSAobGlzdGVuZXJzLmxlbmd0aClcbiAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2xpc3RlbmVycy5sZW5ndGggLSAxXSk7XG4gIH1cbiAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIgcmV0O1xuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIHJldCA9IFtdO1xuICBlbHNlIGlmIChpc0Z1bmN0aW9uKHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgcmV0ID0gW3RoaXMuX2V2ZW50c1t0eXBlXV07XG4gIGVsc2VcbiAgICByZXQgPSB0aGlzLl9ldmVudHNbdHlwZV0uc2xpY2UoKTtcbiAgcmV0dXJuIHJldDtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgaWYgKHRoaXMuX2V2ZW50cykge1xuICAgIHZhciBldmxpc3RlbmVyID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gICAgaWYgKGlzRnVuY3Rpb24oZXZsaXN0ZW5lcikpXG4gICAgICByZXR1cm4gMTtcbiAgICBlbHNlIGlmIChldmxpc3RlbmVyKVxuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICB9XG4gIHJldHVybiAwO1xufTtcblxuRXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlKSB7XG4gIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG59O1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09PSB2b2lkIDA7XG59XG4iLCJpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gIH1cbn1cbiIsIi8qKlxuICogRGV0ZXJtaW5lIGlmIGFuIG9iamVjdCBpcyBCdWZmZXJcbiAqXG4gKiBBdXRob3I6ICAgRmVyb3NzIEFib3VraGFkaWplaCA8ZmVyb3NzQGZlcm9zcy5vcmc+IDxodHRwOi8vZmVyb3NzLm9yZz5cbiAqIExpY2Vuc2U6ICBNSVRcbiAqXG4gKiBgbnBtIGluc3RhbGwgaXMtYnVmZmVyYFxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9iaikge1xuICByZXR1cm4gISEob2JqICE9IG51bGwgJiZcbiAgICAob2JqLl9pc0J1ZmZlciB8fCAvLyBGb3IgU2FmYXJpIDUtNyAobWlzc2luZyBPYmplY3QucHJvdG90eXBlLmNvbnN0cnVjdG9yKVxuICAgICAgKG9iai5jb25zdHJ1Y3RvciAmJlxuICAgICAgdHlwZW9mIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlciA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyKG9iaikpXG4gICAgKSlcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoYXJyKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xudmFyIGN1cnJlbnRRdWV1ZTtcbnZhciBxdWV1ZUluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpIHtcbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXVlID0gY3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgIH1cbiAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIGRyYWluUXVldWUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuXG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG59XG5cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcbiAgICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuICAgICAgICBzZXRUaW1lb3V0KGRyYWluUXVldWUsIDApO1xuICAgIH1cbn07XG5cbi8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcbmZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuICAgIHRoaXMuZnVuID0gZnVuO1xuICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcbn1cbkl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcbn07XG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi9saWIvX3N0cmVhbV9kdXBsZXguanNcIilcbiIsIi8vIGEgZHVwbGV4IHN0cmVhbSBpcyBqdXN0IGEgc3RyZWFtIHRoYXQgaXMgYm90aCByZWFkYWJsZSBhbmQgd3JpdGFibGUuXG4vLyBTaW5jZSBKUyBkb2Vzbid0IGhhdmUgbXVsdGlwbGUgcHJvdG90eXBhbCBpbmhlcml0YW5jZSwgdGhpcyBjbGFzc1xuLy8gcHJvdG90eXBhbGx5IGluaGVyaXRzIGZyb20gUmVhZGFibGUsIGFuZCB0aGVuIHBhcmFzaXRpY2FsbHkgZnJvbVxuLy8gV3JpdGFibGUuXG5cbid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iaikge1xuICB2YXIga2V5cyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSBrZXlzLnB1c2goa2V5KTtcbiAgcmV0dXJuIGtleXM7XG59XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuXG5tb2R1bGUuZXhwb3J0cyA9IER1cGxleDtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBwcm9jZXNzTmV4dFRpY2sgPSByZXF1aXJlKCdwcm9jZXNzLW5leHRpY2stYXJncycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cblxuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSByZXF1aXJlKCdjb3JlLXV0aWwtaXMnKTtcbnV0aWwuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBSZWFkYWJsZSA9IHJlcXVpcmUoJy4vX3N0cmVhbV9yZWFkYWJsZScpO1xudmFyIFdyaXRhYmxlID0gcmVxdWlyZSgnLi9fc3RyZWFtX3dyaXRhYmxlJyk7XG5cbnV0aWwuaW5oZXJpdHMoRHVwbGV4LCBSZWFkYWJsZSk7XG5cbnZhciBrZXlzID0gb2JqZWN0S2V5cyhXcml0YWJsZS5wcm90b3R5cGUpO1xuZm9yICh2YXIgdiA9IDA7IHYgPCBrZXlzLmxlbmd0aDsgdisrKSB7XG4gIHZhciBtZXRob2QgPSBrZXlzW3ZdO1xuICBpZiAoIUR1cGxleC5wcm90b3R5cGVbbWV0aG9kXSlcbiAgICBEdXBsZXgucHJvdG90eXBlW21ldGhvZF0gPSBXcml0YWJsZS5wcm90b3R5cGVbbWV0aG9kXTtcbn1cblxuZnVuY3Rpb24gRHVwbGV4KG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpXG4gICAgcmV0dXJuIG5ldyBEdXBsZXgob3B0aW9ucyk7XG5cbiAgUmVhZGFibGUuY2FsbCh0aGlzLCBvcHRpb25zKTtcbiAgV3JpdGFibGUuY2FsbCh0aGlzLCBvcHRpb25zKTtcblxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLnJlYWRhYmxlID09PSBmYWxzZSlcbiAgICB0aGlzLnJlYWRhYmxlID0gZmFsc2U7XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy53cml0YWJsZSA9PT0gZmFsc2UpXG4gICAgdGhpcy53cml0YWJsZSA9IGZhbHNlO1xuXG4gIHRoaXMuYWxsb3dIYWxmT3BlbiA9IHRydWU7XG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMuYWxsb3dIYWxmT3BlbiA9PT0gZmFsc2UpXG4gICAgdGhpcy5hbGxvd0hhbGZPcGVuID0gZmFsc2U7XG5cbiAgdGhpcy5vbmNlKCdlbmQnLCBvbmVuZCk7XG59XG5cbi8vIHRoZSBuby1oYWxmLW9wZW4gZW5mb3JjZXJcbmZ1bmN0aW9uIG9uZW5kKCkge1xuICAvLyBpZiB3ZSBhbGxvdyBoYWxmLW9wZW4gc3RhdGUsIG9yIGlmIHRoZSB3cml0YWJsZSBzaWRlIGVuZGVkLFxuICAvLyB0aGVuIHdlJ3JlIG9rLlxuICBpZiAodGhpcy5hbGxvd0hhbGZPcGVuIHx8IHRoaXMuX3dyaXRhYmxlU3RhdGUuZW5kZWQpXG4gICAgcmV0dXJuO1xuXG4gIC8vIG5vIG1vcmUgZGF0YSBjYW4gYmUgd3JpdHRlbi5cbiAgLy8gQnV0IGFsbG93IG1vcmUgd3JpdGVzIHRvIGhhcHBlbiBpbiB0aGlzIHRpY2suXG4gIHByb2Nlc3NOZXh0VGljayhvbkVuZE5ULCB0aGlzKTtcbn1cblxuZnVuY3Rpb24gb25FbmROVChzZWxmKSB7XG4gIHNlbGYuZW5kKCk7XG59XG5cbmZ1bmN0aW9uIGZvckVhY2ggKHhzLCBmKSB7XG4gIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgZih4c1tpXSwgaSk7XG4gIH1cbn1cbiIsIi8vIGEgcGFzc3Rocm91Z2ggc3RyZWFtLlxuLy8gYmFzaWNhbGx5IGp1c3QgdGhlIG1vc3QgbWluaW1hbCBzb3J0IG9mIFRyYW5zZm9ybSBzdHJlYW0uXG4vLyBFdmVyeSB3cml0dGVuIGNodW5rIGdldHMgb3V0cHV0IGFzLWlzLlxuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gUGFzc1Rocm91Z2g7XG5cbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCcuL19zdHJlYW1fdHJhbnNmb3JtJyk7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudXRpbC5pbmhlcml0cyhQYXNzVGhyb3VnaCwgVHJhbnNmb3JtKTtcblxuZnVuY3Rpb24gUGFzc1Rocm91Z2gob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUGFzc1Rocm91Z2gpKVxuICAgIHJldHVybiBuZXcgUGFzc1Rocm91Z2gob3B0aW9ucyk7XG5cbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgb3B0aW9ucyk7XG59XG5cblBhc3NUaHJvdWdoLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjYihudWxsLCBjaHVuayk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWRhYmxlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHByb2Nlc3NOZXh0VGljayA9IHJlcXVpcmUoJ3Byb2Nlc3MtbmV4dGljay1hcmdzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpc2FycmF5Jyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5SZWFkYWJsZS5SZWFkYWJsZVN0YXRlID0gUmVhZGFibGVTdGF0ZTtcblxudmFyIEVFID0gcmVxdWlyZSgnZXZlbnRzJyk7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgRUVsaXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICByZXR1cm4gZW1pdHRlci5saXN0ZW5lcnModHlwZSkubGVuZ3RoO1xufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBTdHJlYW07XG4oZnVuY3Rpb24gKCl7dHJ5e1xuICBTdHJlYW0gPSByZXF1aXJlKCdzdCcgKyAncmVhbScpO1xufWNhdGNoKF8pe31maW5hbGx5e1xuICBpZiAoIVN0cmVhbSlcbiAgICBTdHJlYW0gPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG59fSgpKVxuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgZGVidWdVdGlsID0gcmVxdWlyZSgndXRpbCcpO1xudmFyIGRlYnVnO1xuaWYgKGRlYnVnVXRpbCAmJiBkZWJ1Z1V0aWwuZGVidWdsb2cpIHtcbiAgZGVidWcgPSBkZWJ1Z1V0aWwuZGVidWdsb2coJ3N0cmVhbScpO1xufSBlbHNlIHtcbiAgZGVidWcgPSBmdW5jdGlvbiAoKSB7fTtcbn1cbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgU3RyaW5nRGVjb2RlcjtcblxudXRpbC5pbmhlcml0cyhSZWFkYWJsZSwgU3RyZWFtKTtcblxudmFyIER1cGxleDtcbmZ1bmN0aW9uIFJlYWRhYmxlU3RhdGUob3B0aW9ucywgc3RyZWFtKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgLy8gb2JqZWN0IHN0cmVhbSBmbGFnLiBVc2VkIHRvIG1ha2UgcmVhZChuKSBpZ25vcmUgbiBhbmQgdG9cbiAgLy8gbWFrZSBhbGwgdGhlIGJ1ZmZlciBtZXJnaW5nIGFuZCBsZW5ndGggY2hlY2tzIGdvIGF3YXlcbiAgdGhpcy5vYmplY3RNb2RlID0gISFvcHRpb25zLm9iamVjdE1vZGU7XG5cbiAgaWYgKHN0cmVhbSBpbnN0YW5jZW9mIER1cGxleClcbiAgICB0aGlzLm9iamVjdE1vZGUgPSB0aGlzLm9iamVjdE1vZGUgfHwgISFvcHRpb25zLnJlYWRhYmxlT2JqZWN0TW9kZTtcblxuICAvLyB0aGUgcG9pbnQgYXQgd2hpY2ggaXQgc3RvcHMgY2FsbGluZyBfcmVhZCgpIHRvIGZpbGwgdGhlIGJ1ZmZlclxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIFwiZG9uJ3QgY2FsbCBfcmVhZCBwcmVlbXB0aXZlbHkgZXZlclwiXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHZhciBkZWZhdWx0SHdtID0gdGhpcy5vYmplY3RNb2RlID8gMTYgOiAxNiAqIDEwMjQ7XG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IChod20gfHwgaHdtID09PSAwKSA/IGh3bSA6IGRlZmF1bHRId207XG5cbiAgLy8gY2FzdCB0byBpbnRzLlxuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSB+fnRoaXMuaGlnaFdhdGVyTWFyaztcblxuICB0aGlzLmJ1ZmZlciA9IFtdO1xuICB0aGlzLmxlbmd0aCA9IDA7XG4gIHRoaXMucGlwZXMgPSBudWxsO1xuICB0aGlzLnBpcGVzQ291bnQgPSAwO1xuICB0aGlzLmZsb3dpbmcgPSBudWxsO1xuICB0aGlzLmVuZGVkID0gZmFsc2U7XG4gIHRoaXMuZW5kRW1pdHRlZCA9IGZhbHNlO1xuICB0aGlzLnJlYWRpbmcgPSBmYWxzZTtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBvbndyaXRlIGNiIGlzIGNhbGxlZCBpbW1lZGlhdGVseSxcbiAgLy8gb3Igb24gYSBsYXRlciB0aWNrLiAgV2Ugc2V0IHRoaXMgdG8gdHJ1ZSBhdCBmaXJzdCwgYmVjYXVzZSBhbnlcbiAgLy8gYWN0aW9ucyB0aGF0IHNob3VsZG4ndCBoYXBwZW4gdW50aWwgXCJsYXRlclwiIHNob3VsZCBnZW5lcmFsbHkgYWxzb1xuICAvLyBub3QgaGFwcGVuIGJlZm9yZSB0aGUgZmlyc3Qgd3JpdGUgY2FsbC5cbiAgdGhpcy5zeW5jID0gdHJ1ZTtcblxuICAvLyB3aGVuZXZlciB3ZSByZXR1cm4gbnVsbCwgdGhlbiB3ZSBzZXQgYSBmbGFnIHRvIHNheVxuICAvLyB0aGF0IHdlJ3JlIGF3YWl0aW5nIGEgJ3JlYWRhYmxlJyBldmVudCBlbWlzc2lvbi5cbiAgdGhpcy5uZWVkUmVhZGFibGUgPSBmYWxzZTtcbiAgdGhpcy5lbWl0dGVkUmVhZGFibGUgPSBmYWxzZTtcbiAgdGhpcy5yZWFkYWJsZUxpc3RlbmluZyA9IGZhbHNlO1xuXG4gIC8vIENyeXB0byBpcyBraW5kIG9mIG9sZCBhbmQgY3J1c3R5LiAgSGlzdG9yaWNhbGx5LCBpdHMgZGVmYXVsdCBzdHJpbmdcbiAgLy8gZW5jb2RpbmcgaXMgJ2JpbmFyeScgc28gd2UgaGF2ZSB0byBtYWtlIHRoaXMgY29uZmlndXJhYmxlLlxuICAvLyBFdmVyeXRoaW5nIGVsc2UgaW4gdGhlIHVuaXZlcnNlIHVzZXMgJ3V0ZjgnLCB0aG91Z2guXG4gIHRoaXMuZGVmYXVsdEVuY29kaW5nID0gb3B0aW9ucy5kZWZhdWx0RW5jb2RpbmcgfHwgJ3V0ZjgnO1xuXG4gIC8vIHdoZW4gcGlwaW5nLCB3ZSBvbmx5IGNhcmUgYWJvdXQgJ3JlYWRhYmxlJyBldmVudHMgdGhhdCBoYXBwZW5cbiAgLy8gYWZ0ZXIgcmVhZCgpaW5nIGFsbCB0aGUgYnl0ZXMgYW5kIG5vdCBnZXR0aW5nIGFueSBwdXNoYmFjay5cbiAgdGhpcy5yYW5PdXQgPSBmYWxzZTtcblxuICAvLyB0aGUgbnVtYmVyIG9mIHdyaXRlcnMgdGhhdCBhcmUgYXdhaXRpbmcgYSBkcmFpbiBldmVudCBpbiAucGlwZSgpc1xuICB0aGlzLmF3YWl0RHJhaW4gPSAwO1xuXG4gIC8vIGlmIHRydWUsIGEgbWF5YmVSZWFkTW9yZSBoYXMgYmVlbiBzY2hlZHVsZWRcbiAgdGhpcy5yZWFkaW5nTW9yZSA9IGZhbHNlO1xuXG4gIHRoaXMuZGVjb2RlciA9IG51bGw7XG4gIHRoaXMuZW5jb2RpbmcgPSBudWxsO1xuICBpZiAob3B0aW9ucy5lbmNvZGluZykge1xuICAgIGlmICghU3RyaW5nRGVjb2RlcilcbiAgICAgIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2Rlci8nKS5TdHJpbmdEZWNvZGVyO1xuICAgIHRoaXMuZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKG9wdGlvbnMuZW5jb2RpbmcpO1xuICAgIHRoaXMuZW5jb2RpbmcgPSBvcHRpb25zLmVuY29kaW5nO1xuICB9XG59XG5cbnZhciBEdXBsZXg7XG5mdW5jdGlvbiBSZWFkYWJsZShvcHRpb25zKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJlYWRhYmxlKSlcbiAgICByZXR1cm4gbmV3IFJlYWRhYmxlKG9wdGlvbnMpO1xuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUgPSBuZXcgUmVhZGFibGVTdGF0ZShvcHRpb25zLCB0aGlzKTtcblxuICAvLyBsZWdhY3lcbiAgdGhpcy5yZWFkYWJsZSA9IHRydWU7XG5cbiAgaWYgKG9wdGlvbnMgJiYgdHlwZW9mIG9wdGlvbnMucmVhZCA9PT0gJ2Z1bmN0aW9uJylcbiAgICB0aGlzLl9yZWFkID0gb3B0aW9ucy5yZWFkO1xuXG4gIFN0cmVhbS5jYWxsKHRoaXMpO1xufVxuXG4vLyBNYW51YWxseSBzaG92ZSBzb21ldGhpbmcgaW50byB0aGUgcmVhZCgpIGJ1ZmZlci5cbi8vIFRoaXMgcmV0dXJucyB0cnVlIGlmIHRoZSBoaWdoV2F0ZXJNYXJrIGhhcyBub3QgYmVlbiBoaXQgeWV0LFxuLy8gc2ltaWxhciB0byBob3cgV3JpdGFibGUud3JpdGUoKSByZXR1cm5zIHRydWUgaWYgeW91IHNob3VsZFxuLy8gd3JpdGUoKSBzb21lIG1vcmUuXG5SZWFkYWJsZS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uKGNodW5rLCBlbmNvZGluZykge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuXG4gIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJiB0eXBlb2YgY2h1bmsgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBlbmNvZGluZyB8fCBzdGF0ZS5kZWZhdWx0RW5jb2Rpbmc7XG4gICAgaWYgKGVuY29kaW5nICE9PSBzdGF0ZS5lbmNvZGluZykge1xuICAgICAgY2h1bmsgPSBuZXcgQnVmZmVyKGNodW5rLCBlbmNvZGluZyk7XG4gICAgICBlbmNvZGluZyA9ICcnO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZWFkYWJsZUFkZENodW5rKHRoaXMsIHN0YXRlLCBjaHVuaywgZW5jb2RpbmcsIGZhbHNlKTtcbn07XG5cbi8vIFVuc2hpZnQgc2hvdWxkICphbHdheXMqIGJlIHNvbWV0aGluZyBkaXJlY3RseSBvdXQgb2YgcmVhZCgpXG5SZWFkYWJsZS5wcm90b3R5cGUudW5zaGlmdCA9IGZ1bmN0aW9uKGNodW5rKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHJldHVybiByZWFkYWJsZUFkZENodW5rKHRoaXMsIHN0YXRlLCBjaHVuaywgJycsIHRydWUpO1xufTtcblxuUmVhZGFibGUucHJvdG90eXBlLmlzUGF1c2VkID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgPT09IGZhbHNlO1xufTtcblxuZnVuY3Rpb24gcmVhZGFibGVBZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgZW5jb2RpbmcsIGFkZFRvRnJvbnQpIHtcbiAgdmFyIGVyID0gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuayk7XG4gIGlmIChlcikge1xuICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgfSBlbHNlIGlmIChjaHVuayA9PT0gbnVsbCkge1xuICAgIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcbiAgICBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpO1xuICB9IGVsc2UgaWYgKHN0YXRlLm9iamVjdE1vZGUgfHwgY2h1bmsgJiYgY2h1bmsubGVuZ3RoID4gMCkge1xuICAgIGlmIChzdGF0ZS5lbmRlZCAmJiAhYWRkVG9Gcm9udCkge1xuICAgICAgdmFyIGUgPSBuZXcgRXJyb3IoJ3N0cmVhbS5wdXNoKCkgYWZ0ZXIgRU9GJyk7XG4gICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlKTtcbiAgICB9IGVsc2UgaWYgKHN0YXRlLmVuZEVtaXR0ZWQgJiYgYWRkVG9Gcm9udCkge1xuICAgICAgdmFyIGUgPSBuZXcgRXJyb3IoJ3N0cmVhbS51bnNoaWZ0KCkgYWZ0ZXIgZW5kIGV2ZW50Jyk7XG4gICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHN0YXRlLmRlY29kZXIgJiYgIWFkZFRvRnJvbnQgJiYgIWVuY29kaW5nKVxuICAgICAgICBjaHVuayA9IHN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO1xuXG4gICAgICBpZiAoIWFkZFRvRnJvbnQpXG4gICAgICAgIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcblxuICAgICAgLy8gaWYgd2Ugd2FudCB0aGUgZGF0YSBub3csIGp1c3QgZW1pdCBpdC5cbiAgICAgIGlmIChzdGF0ZS5mbG93aW5nICYmIHN0YXRlLmxlbmd0aCA9PT0gMCAmJiAhc3RhdGUuc3luYykge1xuICAgICAgICBzdHJlYW0uZW1pdCgnZGF0YScsIGNodW5rKTtcbiAgICAgICAgc3RyZWFtLnJlYWQoMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyB1cGRhdGUgdGhlIGJ1ZmZlciBpbmZvLlxuICAgICAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgICAgIGlmIChhZGRUb0Zyb250KVxuICAgICAgICAgIHN0YXRlLmJ1ZmZlci51bnNoaWZ0KGNodW5rKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtcblxuICAgICAgICBpZiAoc3RhdGUubmVlZFJlYWRhYmxlKVxuICAgICAgICAgIGVtaXRSZWFkYWJsZShzdHJlYW0pO1xuICAgICAgfVxuXG4gICAgICBtYXliZVJlYWRNb3JlKHN0cmVhbSwgc3RhdGUpO1xuICAgIH1cbiAgfSBlbHNlIGlmICghYWRkVG9Gcm9udCkge1xuICAgIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBuZWVkTW9yZURhdGEoc3RhdGUpO1xufVxuXG5cbi8vIGlmIGl0J3MgcGFzdCB0aGUgaGlnaCB3YXRlciBtYXJrLCB3ZSBjYW4gcHVzaCBpbiBzb21lIG1vcmUuXG4vLyBBbHNvLCBpZiB3ZSBoYXZlIG5vIGRhdGEgeWV0LCB3ZSBjYW4gc3RhbmQgc29tZVxuLy8gbW9yZSBieXRlcy4gIFRoaXMgaXMgdG8gd29yayBhcm91bmQgY2FzZXMgd2hlcmUgaHdtPTAsXG4vLyBzdWNoIGFzIHRoZSByZXBsLiAgQWxzbywgaWYgdGhlIHB1c2goKSB0cmlnZ2VyZWQgYVxuLy8gcmVhZGFibGUgZXZlbnQsIGFuZCB0aGUgdXNlciBjYWxsZWQgcmVhZChsYXJnZU51bWJlcikgc3VjaCB0aGF0XG4vLyBuZWVkUmVhZGFibGUgd2FzIHNldCwgdGhlbiB3ZSBvdWdodCB0byBwdXNoIG1vcmUsIHNvIHRoYXQgYW5vdGhlclxuLy8gJ3JlYWRhYmxlJyBldmVudCB3aWxsIGJlIHRyaWdnZXJlZC5cbmZ1bmN0aW9uIG5lZWRNb3JlRGF0YShzdGF0ZSkge1xuICByZXR1cm4gIXN0YXRlLmVuZGVkICYmXG4gICAgICAgICAoc3RhdGUubmVlZFJlYWRhYmxlIHx8XG4gICAgICAgICAgc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyayB8fFxuICAgICAgICAgIHN0YXRlLmxlbmd0aCA9PT0gMCk7XG59XG5cbi8vIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LlxuUmVhZGFibGUucHJvdG90eXBlLnNldEVuY29kaW5nID0gZnVuY3Rpb24oZW5jKSB7XG4gIGlmICghU3RyaW5nRGVjb2RlcilcbiAgICBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXIvJykuU3RyaW5nRGVjb2RlcjtcbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKTtcbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5lbmNvZGluZyA9IGVuYztcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBEb24ndCByYWlzZSB0aGUgaHdtID4gOE1CXG52YXIgTUFYX0hXTSA9IDB4ODAwMDAwO1xuZnVuY3Rpb24gY29tcHV0ZU5ld0hpZ2hXYXRlck1hcmsobikge1xuICBpZiAobiA+PSBNQVhfSFdNKSB7XG4gICAgbiA9IE1BWF9IV007XG4gIH0gZWxzZSB7XG4gICAgLy8gR2V0IHRoZSBuZXh0IGhpZ2hlc3QgcG93ZXIgb2YgMlxuICAgIG4tLTtcbiAgICBuIHw9IG4gPj4+IDE7XG4gICAgbiB8PSBuID4+PiAyO1xuICAgIG4gfD0gbiA+Pj4gNDtcbiAgICBuIHw9IG4gPj4+IDg7XG4gICAgbiB8PSBuID4+PiAxNjtcbiAgICBuKys7XG4gIH1cbiAgcmV0dXJuIG47XG59XG5cbmZ1bmN0aW9uIGhvd011Y2hUb1JlYWQobiwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5lbmRlZClcbiAgICByZXR1cm4gMDtcblxuICBpZiAoc3RhdGUub2JqZWN0TW9kZSlcbiAgICByZXR1cm4gbiA9PT0gMCA/IDAgOiAxO1xuXG4gIGlmIChuID09PSBudWxsIHx8IGlzTmFOKG4pKSB7XG4gICAgLy8gb25seSBmbG93IG9uZSBidWZmZXIgYXQgYSB0aW1lXG4gICAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUuYnVmZmVyLmxlbmd0aClcbiAgICAgIHJldHVybiBzdGF0ZS5idWZmZXJbMF0ubGVuZ3RoO1xuICAgIGVsc2VcbiAgICAgIHJldHVybiBzdGF0ZS5sZW5ndGg7XG4gIH1cblxuICBpZiAobiA8PSAwKVxuICAgIHJldHVybiAwO1xuXG4gIC8vIElmIHdlJ3JlIGFza2luZyBmb3IgbW9yZSB0aGFuIHRoZSB0YXJnZXQgYnVmZmVyIGxldmVsLFxuICAvLyB0aGVuIHJhaXNlIHRoZSB3YXRlciBtYXJrLiAgQnVtcCB1cCB0byB0aGUgbmV4dCBoaWdoZXN0XG4gIC8vIHBvd2VyIG9mIDIsIHRvIHByZXZlbnQgaW5jcmVhc2luZyBpdCBleGNlc3NpdmVseSBpbiB0aW55XG4gIC8vIGFtb3VudHMuXG4gIGlmIChuID4gc3RhdGUuaGlnaFdhdGVyTWFyaylcbiAgICBzdGF0ZS5oaWdoV2F0ZXJNYXJrID0gY29tcHV0ZU5ld0hpZ2hXYXRlck1hcmsobik7XG5cbiAgLy8gZG9uJ3QgaGF2ZSB0aGF0IG11Y2guICByZXR1cm4gbnVsbCwgdW5sZXNzIHdlJ3ZlIGVuZGVkLlxuICBpZiAobiA+IHN0YXRlLmxlbmd0aCkge1xuICAgIGlmICghc3RhdGUuZW5kZWQpIHtcbiAgICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHN0YXRlLmxlbmd0aDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbjtcbn1cblxuLy8geW91IGNhbiBvdmVycmlkZSBlaXRoZXIgdGhpcyBtZXRob2QsIG9yIHRoZSBhc3luYyBfcmVhZChuKSBiZWxvdy5cblJlYWRhYmxlLnByb3RvdHlwZS5yZWFkID0gZnVuY3Rpb24obikge1xuICBkZWJ1ZygncmVhZCcsIG4pO1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICB2YXIgbk9yaWcgPSBuO1xuXG4gIGlmICh0eXBlb2YgbiAhPT0gJ251bWJlcicgfHwgbiA+IDApXG4gICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG5cbiAgLy8gaWYgd2UncmUgZG9pbmcgcmVhZCgwKSB0byB0cmlnZ2VyIGEgcmVhZGFibGUgZXZlbnQsIGJ1dCB3ZVxuICAvLyBhbHJlYWR5IGhhdmUgYSBidW5jaCBvZiBkYXRhIGluIHRoZSBidWZmZXIsIHRoZW4ganVzdCB0cmlnZ2VyXG4gIC8vIHRoZSAncmVhZGFibGUnIGV2ZW50IGFuZCBtb3ZlIG9uLlxuICBpZiAobiA9PT0gMCAmJlxuICAgICAgc3RhdGUubmVlZFJlYWRhYmxlICYmXG4gICAgICAoc3RhdGUubGVuZ3RoID49IHN0YXRlLmhpZ2hXYXRlck1hcmsgfHwgc3RhdGUuZW5kZWQpKSB7XG4gICAgZGVidWcoJ3JlYWQ6IGVtaXRSZWFkYWJsZScsIHN0YXRlLmxlbmd0aCwgc3RhdGUuZW5kZWQpO1xuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuZW5kZWQpXG4gICAgICBlbmRSZWFkYWJsZSh0aGlzKTtcbiAgICBlbHNlXG4gICAgICBlbWl0UmVhZGFibGUodGhpcyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBuID0gaG93TXVjaFRvUmVhZChuLCBzdGF0ZSk7XG5cbiAgLy8gaWYgd2UndmUgZW5kZWQsIGFuZCB3ZSdyZSBub3cgY2xlYXIsIHRoZW4gZmluaXNoIGl0IHVwLlxuICBpZiAobiA9PT0gMCAmJiBzdGF0ZS5lbmRlZCkge1xuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApXG4gICAgICBlbmRSZWFkYWJsZSh0aGlzKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIEFsbCB0aGUgYWN0dWFsIGNodW5rIGdlbmVyYXRpb24gbG9naWMgbmVlZHMgdG8gYmVcbiAgLy8gKmJlbG93KiB0aGUgY2FsbCB0byBfcmVhZC4gIFRoZSByZWFzb24gaXMgdGhhdCBpbiBjZXJ0YWluXG4gIC8vIHN5bnRoZXRpYyBzdHJlYW0gY2FzZXMsIHN1Y2ggYXMgcGFzc3Rocm91Z2ggc3RyZWFtcywgX3JlYWRcbiAgLy8gbWF5IGJlIGEgY29tcGxldGVseSBzeW5jaHJvbm91cyBvcGVyYXRpb24gd2hpY2ggbWF5IGNoYW5nZVxuICAvLyB0aGUgc3RhdGUgb2YgdGhlIHJlYWQgYnVmZmVyLCBwcm92aWRpbmcgZW5vdWdoIGRhdGEgd2hlblxuICAvLyBiZWZvcmUgdGhlcmUgd2FzICpub3QqIGVub3VnaC5cbiAgLy9cbiAgLy8gU28sIHRoZSBzdGVwcyBhcmU6XG4gIC8vIDEuIEZpZ3VyZSBvdXQgd2hhdCB0aGUgc3RhdGUgb2YgdGhpbmdzIHdpbGwgYmUgYWZ0ZXIgd2UgZG9cbiAgLy8gYSByZWFkIGZyb20gdGhlIGJ1ZmZlci5cbiAgLy9cbiAgLy8gMi4gSWYgdGhhdCByZXN1bHRpbmcgc3RhdGUgd2lsbCB0cmlnZ2VyIGEgX3JlYWQsIHRoZW4gY2FsbCBfcmVhZC5cbiAgLy8gTm90ZSB0aGF0IHRoaXMgbWF5IGJlIGFzeW5jaHJvbm91cywgb3Igc3luY2hyb25vdXMuICBZZXMsIGl0IGlzXG4gIC8vIGRlZXBseSB1Z2x5IHRvIHdyaXRlIEFQSXMgdGhpcyB3YXksIGJ1dCB0aGF0IHN0aWxsIGRvZXNuJ3QgbWVhblxuICAvLyB0aGF0IHRoZSBSZWFkYWJsZSBjbGFzcyBzaG91bGQgYmVoYXZlIGltcHJvcGVybHksIGFzIHN0cmVhbXMgYXJlXG4gIC8vIGRlc2lnbmVkIHRvIGJlIHN5bmMvYXN5bmMgYWdub3N0aWMuXG4gIC8vIFRha2Ugbm90ZSBpZiB0aGUgX3JlYWQgY2FsbCBpcyBzeW5jIG9yIGFzeW5jIChpZSwgaWYgdGhlIHJlYWQgY2FsbFxuICAvLyBoYXMgcmV0dXJuZWQgeWV0KSwgc28gdGhhdCB3ZSBrbm93IHdoZXRoZXIgb3Igbm90IGl0J3Mgc2FmZSB0byBlbWl0XG4gIC8vICdyZWFkYWJsZScgZXRjLlxuICAvL1xuICAvLyAzLiBBY3R1YWxseSBwdWxsIHRoZSByZXF1ZXN0ZWQgY2h1bmtzIG91dCBvZiB0aGUgYnVmZmVyIGFuZCByZXR1cm4uXG5cbiAgLy8gaWYgd2UgbmVlZCBhIHJlYWRhYmxlIGV2ZW50LCB0aGVuIHdlIG5lZWQgdG8gZG8gc29tZSByZWFkaW5nLlxuICB2YXIgZG9SZWFkID0gc3RhdGUubmVlZFJlYWRhYmxlO1xuICBkZWJ1ZygnbmVlZCByZWFkYWJsZScsIGRvUmVhZCk7XG5cbiAgLy8gaWYgd2UgY3VycmVudGx5IGhhdmUgbGVzcyB0aGFuIHRoZSBoaWdoV2F0ZXJNYXJrLCB0aGVuIGFsc28gcmVhZCBzb21lXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgfHwgc3RhdGUubGVuZ3RoIC0gbiA8IHN0YXRlLmhpZ2hXYXRlck1hcmspIHtcbiAgICBkb1JlYWQgPSB0cnVlO1xuICAgIGRlYnVnKCdsZW5ndGggbGVzcyB0aGFuIHdhdGVybWFyaycsIGRvUmVhZCk7XG4gIH1cblxuICAvLyBob3dldmVyLCBpZiB3ZSd2ZSBlbmRlZCwgdGhlbiB0aGVyZSdzIG5vIHBvaW50LCBhbmQgaWYgd2UncmUgYWxyZWFkeVxuICAvLyByZWFkaW5nLCB0aGVuIGl0J3MgdW5uZWNlc3NhcnkuXG4gIGlmIChzdGF0ZS5lbmRlZCB8fCBzdGF0ZS5yZWFkaW5nKSB7XG4gICAgZG9SZWFkID0gZmFsc2U7XG4gICAgZGVidWcoJ3JlYWRpbmcgb3IgZW5kZWQnLCBkb1JlYWQpO1xuICB9XG5cbiAgaWYgKGRvUmVhZCkge1xuICAgIGRlYnVnKCdkbyByZWFkJyk7XG4gICAgc3RhdGUucmVhZGluZyA9IHRydWU7XG4gICAgc3RhdGUuc3luYyA9IHRydWU7XG4gICAgLy8gaWYgdGhlIGxlbmd0aCBpcyBjdXJyZW50bHkgemVybywgdGhlbiB3ZSAqbmVlZCogYSByZWFkYWJsZSBldmVudC5cbiAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwKVxuICAgICAgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICAvLyBjYWxsIGludGVybmFsIHJlYWQgbWV0aG9kXG4gICAgdGhpcy5fcmVhZChzdGF0ZS5oaWdoV2F0ZXJNYXJrKTtcbiAgICBzdGF0ZS5zeW5jID0gZmFsc2U7XG4gIH1cblxuICAvLyBJZiBfcmVhZCBwdXNoZWQgZGF0YSBzeW5jaHJvbm91c2x5LCB0aGVuIGByZWFkaW5nYCB3aWxsIGJlIGZhbHNlLFxuICAvLyBhbmQgd2UgbmVlZCB0byByZS1ldmFsdWF0ZSBob3cgbXVjaCBkYXRhIHdlIGNhbiByZXR1cm4gdG8gdGhlIHVzZXIuXG4gIGlmIChkb1JlYWQgJiYgIXN0YXRlLnJlYWRpbmcpXG4gICAgbiA9IGhvd011Y2hUb1JlYWQobk9yaWcsIHN0YXRlKTtcblxuICB2YXIgcmV0O1xuICBpZiAobiA+IDApXG4gICAgcmV0ID0gZnJvbUxpc3Qobiwgc3RhdGUpO1xuICBlbHNlXG4gICAgcmV0ID0gbnVsbDtcblxuICBpZiAocmV0ID09PSBudWxsKSB7XG4gICAgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICBuID0gMDtcbiAgfVxuXG4gIHN0YXRlLmxlbmd0aCAtPSBuO1xuXG4gIC8vIElmIHdlIGhhdmUgbm90aGluZyBpbiB0aGUgYnVmZmVyLCB0aGVuIHdlIHdhbnQgdG8ga25vd1xuICAvLyBhcyBzb29uIGFzIHdlICpkbyogZ2V0IHNvbWV0aGluZyBpbnRvIHRoZSBidWZmZXIuXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgIXN0YXRlLmVuZGVkKVxuICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG5cbiAgLy8gSWYgd2UgdHJpZWQgdG8gcmVhZCgpIHBhc3QgdGhlIEVPRiwgdGhlbiBlbWl0IGVuZCBvbiB0aGUgbmV4dCB0aWNrLlxuICBpZiAobk9yaWcgIT09IG4gJiYgc3RhdGUuZW5kZWQgJiYgc3RhdGUubGVuZ3RoID09PSAwKVxuICAgIGVuZFJlYWRhYmxlKHRoaXMpO1xuXG4gIGlmIChyZXQgIT09IG51bGwpXG4gICAgdGhpcy5lbWl0KCdkYXRhJywgcmV0KTtcblxuICByZXR1cm4gcmV0O1xufTtcblxuZnVuY3Rpb24gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuaykge1xuICB2YXIgZXIgPSBudWxsO1xuICBpZiAoIShCdWZmZXIuaXNCdWZmZXIoY2h1bmspKSAmJlxuICAgICAgdHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJyAmJlxuICAgICAgY2h1bmsgIT09IG51bGwgJiZcbiAgICAgIGNodW5rICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICFzdGF0ZS5vYmplY3RNb2RlKSB7XG4gICAgZXIgPSBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rJyk7XG4gIH1cbiAgcmV0dXJuIGVyO1xufVxuXG5cbmZ1bmN0aW9uIG9uRW9mQ2h1bmsoc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoc3RhdGUuZW5kZWQpIHJldHVybjtcbiAgaWYgKHN0YXRlLmRlY29kZXIpIHtcbiAgICB2YXIgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLmVuZCgpO1xuICAgIGlmIChjaHVuayAmJiBjaHVuay5sZW5ndGgpIHtcbiAgICAgIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtcbiAgICAgIHN0YXRlLmxlbmd0aCArPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcbiAgICB9XG4gIH1cbiAgc3RhdGUuZW5kZWQgPSB0cnVlO1xuXG4gIC8vIGVtaXQgJ3JlYWRhYmxlJyBub3cgdG8gbWFrZSBzdXJlIGl0IGdldHMgcGlja2VkIHVwLlxuICBlbWl0UmVhZGFibGUoc3RyZWFtKTtcbn1cblxuLy8gRG9uJ3QgZW1pdCByZWFkYWJsZSByaWdodCBhd2F5IGluIHN5bmMgbW9kZSwgYmVjYXVzZSB0aGlzIGNhbiB0cmlnZ2VyXG4vLyBhbm90aGVyIHJlYWQoKSBjYWxsID0+IHN0YWNrIG92ZXJmbG93LiAgVGhpcyB3YXksIGl0IG1pZ2h0IHRyaWdnZXJcbi8vIGEgbmV4dFRpY2sgcmVjdXJzaW9uIHdhcm5pbmcsIGJ1dCB0aGF0J3Mgbm90IHNvIGJhZC5cbmZ1bmN0aW9uIGVtaXRSZWFkYWJsZShzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICBzdGF0ZS5uZWVkUmVhZGFibGUgPSBmYWxzZTtcbiAgaWYgKCFzdGF0ZS5lbWl0dGVkUmVhZGFibGUpIHtcbiAgICBkZWJ1ZygnZW1pdFJlYWRhYmxlJywgc3RhdGUuZmxvd2luZyk7XG4gICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICBpZiAoc3RhdGUuc3luYylcbiAgICAgIHByb2Nlc3NOZXh0VGljayhlbWl0UmVhZGFibGVfLCBzdHJlYW0pO1xuICAgIGVsc2VcbiAgICAgIGVtaXRSZWFkYWJsZV8oc3RyZWFtKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbWl0UmVhZGFibGVfKHN0cmVhbSkge1xuICBkZWJ1ZygnZW1pdCByZWFkYWJsZScpO1xuICBzdHJlYW0uZW1pdCgncmVhZGFibGUnKTtcbiAgZmxvdyhzdHJlYW0pO1xufVxuXG5cbi8vIGF0IHRoaXMgcG9pbnQsIHRoZSB1c2VyIGhhcyBwcmVzdW1hYmx5IHNlZW4gdGhlICdyZWFkYWJsZScgZXZlbnQsXG4vLyBhbmQgY2FsbGVkIHJlYWQoKSB0byBjb25zdW1lIHNvbWUgZGF0YS4gIHRoYXQgbWF5IGhhdmUgdHJpZ2dlcmVkXG4vLyBpbiB0dXJuIGFub3RoZXIgX3JlYWQobikgY2FsbCwgaW4gd2hpY2ggY2FzZSByZWFkaW5nID0gdHJ1ZSBpZlxuLy8gaXQncyBpbiBwcm9ncmVzcy5cbi8vIEhvd2V2ZXIsIGlmIHdlJ3JlIG5vdCBlbmRlZCwgb3IgcmVhZGluZywgYW5kIHRoZSBsZW5ndGggPCBod20sXG4vLyB0aGVuIGdvIGFoZWFkIGFuZCB0cnkgdG8gcmVhZCBzb21lIG1vcmUgcHJlZW1wdGl2ZWx5LlxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVhZGluZ01vcmUpIHtcbiAgICBzdGF0ZS5yZWFkaW5nTW9yZSA9IHRydWU7XG4gICAgcHJvY2Vzc05leHRUaWNrKG1heWJlUmVhZE1vcmVfLCBzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtYXliZVJlYWRNb3JlXyhzdHJlYW0sIHN0YXRlKSB7XG4gIHZhciBsZW4gPSBzdGF0ZS5sZW5ndGg7XG4gIHdoaWxlICghc3RhdGUucmVhZGluZyAmJiAhc3RhdGUuZmxvd2luZyAmJiAhc3RhdGUuZW5kZWQgJiZcbiAgICAgICAgIHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcmspIHtcbiAgICBkZWJ1ZygnbWF5YmVSZWFkTW9yZSByZWFkIDAnKTtcbiAgICBzdHJlYW0ucmVhZCgwKTtcbiAgICBpZiAobGVuID09PSBzdGF0ZS5sZW5ndGgpXG4gICAgICAvLyBkaWRuJ3QgZ2V0IGFueSBkYXRhLCBzdG9wIHNwaW5uaW5nLlxuICAgICAgYnJlYWs7XG4gICAgZWxzZVxuICAgICAgbGVuID0gc3RhdGUubGVuZ3RoO1xuICB9XG4gIHN0YXRlLnJlYWRpbmdNb3JlID0gZmFsc2U7XG59XG5cbi8vIGFic3RyYWN0IG1ldGhvZC4gIHRvIGJlIG92ZXJyaWRkZW4gaW4gc3BlY2lmaWMgaW1wbGVtZW50YXRpb24gY2xhc3Nlcy5cbi8vIGNhbGwgY2IoZXIsIGRhdGEpIHdoZXJlIGRhdGEgaXMgPD0gbiBpbiBsZW5ndGguXG4vLyBmb3IgdmlydHVhbCAobm9uLXN0cmluZywgbm9uLWJ1ZmZlcikgc3RyZWFtcywgXCJsZW5ndGhcIiBpcyBzb21ld2hhdFxuLy8gYXJiaXRyYXJ5LCBhbmQgcGVyaGFwcyBub3QgdmVyeSBtZWFuaW5nZnVsLlxuUmVhZGFibGUucHJvdG90eXBlLl9yZWFkID0gZnVuY3Rpb24obikge1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdub3QgaW1wbGVtZW50ZWQnKSk7XG59O1xuXG5SZWFkYWJsZS5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uKGRlc3QsIHBpcGVPcHRzKSB7XG4gIHZhciBzcmMgPSB0aGlzO1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuXG4gIHN3aXRjaCAoc3RhdGUucGlwZXNDb3VudCkge1xuICAgIGNhc2UgMDpcbiAgICAgIHN0YXRlLnBpcGVzID0gZGVzdDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMTpcbiAgICAgIHN0YXRlLnBpcGVzID0gW3N0YXRlLnBpcGVzLCBkZXN0XTtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBzdGF0ZS5waXBlcy5wdXNoKGRlc3QpO1xuICAgICAgYnJlYWs7XG4gIH1cbiAgc3RhdGUucGlwZXNDb3VudCArPSAxO1xuICBkZWJ1ZygncGlwZSBjb3VudD0lZCBvcHRzPSVqJywgc3RhdGUucGlwZXNDb3VudCwgcGlwZU9wdHMpO1xuXG4gIHZhciBkb0VuZCA9ICghcGlwZU9wdHMgfHwgcGlwZU9wdHMuZW5kICE9PSBmYWxzZSkgJiZcbiAgICAgICAgICAgICAgZGVzdCAhPT0gcHJvY2Vzcy5zdGRvdXQgJiZcbiAgICAgICAgICAgICAgZGVzdCAhPT0gcHJvY2Vzcy5zdGRlcnI7XG5cbiAgdmFyIGVuZEZuID0gZG9FbmQgPyBvbmVuZCA6IGNsZWFudXA7XG4gIGlmIChzdGF0ZS5lbmRFbWl0dGVkKVxuICAgIHByb2Nlc3NOZXh0VGljayhlbmRGbik7XG4gIGVsc2VcbiAgICBzcmMub25jZSgnZW5kJywgZW5kRm4pO1xuXG4gIGRlc3Qub24oJ3VucGlwZScsIG9udW5waXBlKTtcbiAgZnVuY3Rpb24gb251bnBpcGUocmVhZGFibGUpIHtcbiAgICBkZWJ1Zygnb251bnBpcGUnKTtcbiAgICBpZiAocmVhZGFibGUgPT09IHNyYykge1xuICAgICAgY2xlYW51cCgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG9uZW5kKCkge1xuICAgIGRlYnVnKCdvbmVuZCcpO1xuICAgIGRlc3QuZW5kKCk7XG4gIH1cblxuICAvLyB3aGVuIHRoZSBkZXN0IGRyYWlucywgaXQgcmVkdWNlcyB0aGUgYXdhaXREcmFpbiBjb3VudGVyXG4gIC8vIG9uIHRoZSBzb3VyY2UuICBUaGlzIHdvdWxkIGJlIG1vcmUgZWxlZ2FudCB3aXRoIGEgLm9uY2UoKVxuICAvLyBoYW5kbGVyIGluIGZsb3coKSwgYnV0IGFkZGluZyBhbmQgcmVtb3ZpbmcgcmVwZWF0ZWRseSBpc1xuICAvLyB0b28gc2xvdy5cbiAgdmFyIG9uZHJhaW4gPSBwaXBlT25EcmFpbihzcmMpO1xuICBkZXN0Lm9uKCdkcmFpbicsIG9uZHJhaW4pO1xuXG4gIHZhciBjbGVhbmVkVXAgPSBmYWxzZTtcbiAgZnVuY3Rpb24gY2xlYW51cCgpIHtcbiAgICBkZWJ1ZygnY2xlYW51cCcpO1xuICAgIC8vIGNsZWFudXAgZXZlbnQgaGFuZGxlcnMgb25jZSB0aGUgcGlwZSBpcyBicm9rZW5cbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2ZpbmlzaCcsIG9uZmluaXNoKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdkcmFpbicsIG9uZHJhaW4pO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcigndW5waXBlJywgb251bnBpcGUpO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25lbmQpO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZW5kJywgY2xlYW51cCk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgb25kYXRhKTtcblxuICAgIGNsZWFuZWRVcCA9IHRydWU7XG5cbiAgICAvLyBpZiB0aGUgcmVhZGVyIGlzIHdhaXRpbmcgZm9yIGEgZHJhaW4gZXZlbnQgZnJvbSB0aGlzXG4gICAgLy8gc3BlY2lmaWMgd3JpdGVyLCB0aGVuIGl0IHdvdWxkIGNhdXNlIGl0IHRvIG5ldmVyIHN0YXJ0XG4gICAgLy8gZmxvd2luZyBhZ2Fpbi5cbiAgICAvLyBTbywgaWYgdGhpcyBpcyBhd2FpdGluZyBhIGRyYWluLCB0aGVuIHdlIGp1c3QgY2FsbCBpdCBub3cuXG4gICAgLy8gSWYgd2UgZG9uJ3Qga25vdywgdGhlbiBhc3N1bWUgdGhhdCB3ZSBhcmUgd2FpdGluZyBmb3Igb25lLlxuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluICYmXG4gICAgICAgICghZGVzdC5fd3JpdGFibGVTdGF0ZSB8fCBkZXN0Ll93cml0YWJsZVN0YXRlLm5lZWREcmFpbikpXG4gICAgICBvbmRyYWluKCk7XG4gIH1cblxuICBzcmMub24oJ2RhdGEnLCBvbmRhdGEpO1xuICBmdW5jdGlvbiBvbmRhdGEoY2h1bmspIHtcbiAgICBkZWJ1Zygnb25kYXRhJyk7XG4gICAgdmFyIHJldCA9IGRlc3Qud3JpdGUoY2h1bmspO1xuICAgIGlmIChmYWxzZSA9PT0gcmV0KSB7XG4gICAgICAvLyBJZiB0aGUgdXNlciB1bnBpcGVkIGR1cmluZyBgZGVzdC53cml0ZSgpYCwgaXQgaXMgcG9zc2libGVcbiAgICAgIC8vIHRvIGdldCBzdHVjayBpbiBhIHBlcm1hbmVudGx5IHBhdXNlZCBzdGF0ZSBpZiB0aGF0IHdyaXRlXG4gICAgICAvLyBhbHNvIHJldHVybmVkIGZhbHNlLlxuICAgICAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEgJiZcbiAgICAgICAgICBzdGF0ZS5waXBlc1swXSA9PT0gZGVzdCAmJlxuICAgICAgICAgIHNyYy5saXN0ZW5lckNvdW50KCdkYXRhJykgPT09IDEgJiZcbiAgICAgICAgICAhY2xlYW5lZFVwKSB7XG4gICAgICAgIGRlYnVnKCdmYWxzZSB3cml0ZSByZXNwb25zZSwgcGF1c2UnLCBzcmMuX3JlYWRhYmxlU3RhdGUuYXdhaXREcmFpbik7XG4gICAgICAgIHNyYy5fcmVhZGFibGVTdGF0ZS5hd2FpdERyYWluKys7XG4gICAgICB9XG4gICAgICBzcmMucGF1c2UoKTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgZGVzdCBoYXMgYW4gZXJyb3IsIHRoZW4gc3RvcCBwaXBpbmcgaW50byBpdC5cbiAgLy8gaG93ZXZlciwgZG9uJ3Qgc3VwcHJlc3MgdGhlIHRocm93aW5nIGJlaGF2aW9yIGZvciB0aGlzLlxuICBmdW5jdGlvbiBvbmVycm9yKGVyKSB7XG4gICAgZGVidWcoJ29uZXJyb3InLCBlcik7XG4gICAgdW5waXBlKCk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBpZiAoRUVsaXN0ZW5lckNvdW50KGRlc3QsICdlcnJvcicpID09PSAwKVxuICAgICAgZGVzdC5lbWl0KCdlcnJvcicsIGVyKTtcbiAgfVxuICAvLyBUaGlzIGlzIGEgYnJ1dGFsbHkgdWdseSBoYWNrIHRvIG1ha2Ugc3VyZSB0aGF0IG91ciBlcnJvciBoYW5kbGVyXG4gIC8vIGlzIGF0dGFjaGVkIGJlZm9yZSBhbnkgdXNlcmxhbmQgb25lcy4gIE5FVkVSIERPIFRISVMuXG4gIGlmICghZGVzdC5fZXZlbnRzIHx8ICFkZXN0Ll9ldmVudHMuZXJyb3IpXG4gICAgZGVzdC5vbignZXJyb3InLCBvbmVycm9yKTtcbiAgZWxzZSBpZiAoaXNBcnJheShkZXN0Ll9ldmVudHMuZXJyb3IpKVxuICAgIGRlc3QuX2V2ZW50cy5lcnJvci51bnNoaWZ0KG9uZXJyb3IpO1xuICBlbHNlXG4gICAgZGVzdC5fZXZlbnRzLmVycm9yID0gW29uZXJyb3IsIGRlc3QuX2V2ZW50cy5lcnJvcl07XG5cblxuICAvLyBCb3RoIGNsb3NlIGFuZCBmaW5pc2ggc2hvdWxkIHRyaWdnZXIgdW5waXBlLCBidXQgb25seSBvbmNlLlxuICBmdW5jdGlvbiBvbmNsb3NlKCkge1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2ZpbmlzaCcsIG9uZmluaXNoKTtcbiAgICB1bnBpcGUoKTtcbiAgfVxuICBkZXN0Lm9uY2UoJ2Nsb3NlJywgb25jbG9zZSk7XG4gIGZ1bmN0aW9uIG9uZmluaXNoKCkge1xuICAgIGRlYnVnKCdvbmZpbmlzaCcpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG4gICAgdW5waXBlKCk7XG4gIH1cbiAgZGVzdC5vbmNlKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG5cbiAgZnVuY3Rpb24gdW5waXBlKCkge1xuICAgIGRlYnVnKCd1bnBpcGUnKTtcbiAgICBzcmMudW5waXBlKGRlc3QpO1xuICB9XG5cbiAgLy8gdGVsbCB0aGUgZGVzdCB0aGF0IGl0J3MgYmVpbmcgcGlwZWQgdG9cbiAgZGVzdC5lbWl0KCdwaXBlJywgc3JjKTtcblxuICAvLyBzdGFydCB0aGUgZmxvdyBpZiBpdCBoYXNuJ3QgYmVlbiBzdGFydGVkIGFscmVhZHkuXG4gIGlmICghc3RhdGUuZmxvd2luZykge1xuICAgIGRlYnVnKCdwaXBlIHJlc3VtZScpO1xuICAgIHNyYy5yZXN1bWUoKTtcbiAgfVxuXG4gIHJldHVybiBkZXN0O1xufTtcblxuZnVuY3Rpb24gcGlwZU9uRHJhaW4oc3JjKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgc3RhdGUgPSBzcmMuX3JlYWRhYmxlU3RhdGU7XG4gICAgZGVidWcoJ3BpcGVPbkRyYWluJywgc3RhdGUuYXdhaXREcmFpbik7XG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4pXG4gICAgICBzdGF0ZS5hd2FpdERyYWluLS07XG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4gPT09IDAgJiYgRUVsaXN0ZW5lckNvdW50KHNyYywgJ2RhdGEnKSkge1xuICAgICAgc3RhdGUuZmxvd2luZyA9IHRydWU7XG4gICAgICBmbG93KHNyYyk7XG4gICAgfVxuICB9O1xufVxuXG5cblJlYWRhYmxlLnByb3RvdHlwZS51bnBpcGUgPSBmdW5jdGlvbihkZXN0KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG5cbiAgLy8gaWYgd2UncmUgbm90IHBpcGluZyBhbnl3aGVyZSwgdGhlbiBkbyBub3RoaW5nLlxuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMClcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBqdXN0IG9uZSBkZXN0aW5hdGlvbi4gIG1vc3QgY29tbW9uIGNhc2UuXG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAxKSB7XG4gICAgLy8gcGFzc2VkIGluIG9uZSwgYnV0IGl0J3Mgbm90IHRoZSByaWdodCBvbmUuXG4gICAgaWYgKGRlc3QgJiYgZGVzdCAhPT0gc3RhdGUucGlwZXMpXG4gICAgICByZXR1cm4gdGhpcztcblxuICAgIGlmICghZGVzdClcbiAgICAgIGRlc3QgPSBzdGF0ZS5waXBlcztcblxuICAgIC8vIGdvdCBhIG1hdGNoLlxuICAgIHN0YXRlLnBpcGVzID0gbnVsbDtcbiAgICBzdGF0ZS5waXBlc0NvdW50ID0gMDtcbiAgICBzdGF0ZS5mbG93aW5nID0gZmFsc2U7XG4gICAgaWYgKGRlc3QpXG4gICAgICBkZXN0LmVtaXQoJ3VucGlwZScsIHRoaXMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gc2xvdyBjYXNlLiBtdWx0aXBsZSBwaXBlIGRlc3RpbmF0aW9ucy5cblxuICBpZiAoIWRlc3QpIHtcbiAgICAvLyByZW1vdmUgYWxsLlxuICAgIHZhciBkZXN0cyA9IHN0YXRlLnBpcGVzO1xuICAgIHZhciBsZW4gPSBzdGF0ZS5waXBlc0NvdW50O1xuICAgIHN0YXRlLnBpcGVzID0gbnVsbDtcbiAgICBzdGF0ZS5waXBlc0NvdW50ID0gMDtcbiAgICBzdGF0ZS5mbG93aW5nID0gZmFsc2U7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKVxuICAgICAgZGVzdHNbaV0uZW1pdCgndW5waXBlJywgdGhpcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyB0cnkgdG8gZmluZCB0aGUgcmlnaHQgb25lLlxuICB2YXIgaSA9IGluZGV4T2Yoc3RhdGUucGlwZXMsIGRlc3QpO1xuICBpZiAoaSA9PT0gLTEpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgc3RhdGUucGlwZXMuc3BsaWNlKGksIDEpO1xuICBzdGF0ZS5waXBlc0NvdW50IC09IDE7XG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAxKVxuICAgIHN0YXRlLnBpcGVzID0gc3RhdGUucGlwZXNbMF07XG5cbiAgZGVzdC5lbWl0KCd1bnBpcGUnLCB0aGlzKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIHNldCB1cCBkYXRhIGV2ZW50cyBpZiB0aGV5IGFyZSBhc2tlZCBmb3Jcbi8vIEVuc3VyZSByZWFkYWJsZSBsaXN0ZW5lcnMgZXZlbnR1YWxseSBnZXQgc29tZXRoaW5nXG5SZWFkYWJsZS5wcm90b3R5cGUub24gPSBmdW5jdGlvbihldiwgZm4pIHtcbiAgdmFyIHJlcyA9IFN0cmVhbS5wcm90b3R5cGUub24uY2FsbCh0aGlzLCBldiwgZm4pO1xuXG4gIC8vIElmIGxpc3RlbmluZyB0byBkYXRhLCBhbmQgaXQgaGFzIG5vdCBleHBsaWNpdGx5IGJlZW4gcGF1c2VkLFxuICAvLyB0aGVuIGNhbGwgcmVzdW1lIHRvIHN0YXJ0IHRoZSBmbG93IG9mIGRhdGEgb24gdGhlIG5leHQgdGljay5cbiAgaWYgKGV2ID09PSAnZGF0YScgJiYgZmFsc2UgIT09IHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZykge1xuICAgIHRoaXMucmVzdW1lKCk7XG4gIH1cblxuICBpZiAoZXYgPT09ICdyZWFkYWJsZScgJiYgdGhpcy5yZWFkYWJsZSkge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gICAgaWYgKCFzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZykge1xuICAgICAgc3RhdGUucmVhZGFibGVMaXN0ZW5pbmcgPSB0cnVlO1xuICAgICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gICAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgICAgaWYgKCFzdGF0ZS5yZWFkaW5nKSB7XG4gICAgICAgIHByb2Nlc3NOZXh0VGljayhuUmVhZGluZ05leHRUaWNrLCB0aGlzKTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGVuZ3RoKSB7XG4gICAgICAgIGVtaXRSZWFkYWJsZSh0aGlzLCBzdGF0ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlcztcbn07XG5SZWFkYWJsZS5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBSZWFkYWJsZS5wcm90b3R5cGUub247XG5cbmZ1bmN0aW9uIG5SZWFkaW5nTmV4dFRpY2soc2VsZikge1xuICBkZWJ1ZygncmVhZGFibGUgbmV4dHRpY2sgcmVhZCAwJyk7XG4gIHNlbGYucmVhZCgwKTtcbn1cblxuLy8gcGF1c2UoKSBhbmQgcmVzdW1lKCkgYXJlIHJlbW5hbnRzIG9mIHRoZSBsZWdhY3kgcmVhZGFibGUgc3RyZWFtIEFQSVxuLy8gSWYgdGhlIHVzZXIgdXNlcyB0aGVtLCB0aGVuIHN3aXRjaCBpbnRvIG9sZCBtb2RlLlxuUmVhZGFibGUucHJvdG90eXBlLnJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICBpZiAoIXN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncmVzdW1lJyk7XG4gICAgc3RhdGUuZmxvd2luZyA9IHRydWU7XG4gICAgcmVzdW1lKHRoaXMsIHN0YXRlKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIHJlc3VtZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVzdW1lU2NoZWR1bGVkKSB7XG4gICAgc3RhdGUucmVzdW1lU2NoZWR1bGVkID0gdHJ1ZTtcbiAgICBwcm9jZXNzTmV4dFRpY2socmVzdW1lXywgc3RyZWFtLCBzdGF0ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzdW1lXyhzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVhZGluZykge1xuICAgIGRlYnVnKCdyZXN1bWUgcmVhZCAwJyk7XG4gICAgc3RyZWFtLnJlYWQoMCk7XG4gIH1cblxuICBzdGF0ZS5yZXN1bWVTY2hlZHVsZWQgPSBmYWxzZTtcbiAgc3RyZWFtLmVtaXQoJ3Jlc3VtZScpO1xuICBmbG93KHN0cmVhbSk7XG4gIGlmIChzdGF0ZS5mbG93aW5nICYmICFzdGF0ZS5yZWFkaW5nKVxuICAgIHN0cmVhbS5yZWFkKDApO1xufVxuXG5SZWFkYWJsZS5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbigpIHtcbiAgZGVidWcoJ2NhbGwgcGF1c2UgZmxvd2luZz0laicsIHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyk7XG4gIGlmIChmYWxzZSAhPT0gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKSB7XG4gICAgZGVidWcoJ3BhdXNlJyk7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nID0gZmFsc2U7XG4gICAgdGhpcy5lbWl0KCdwYXVzZScpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gZmxvdyhzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICBkZWJ1ZygnZmxvdycsIHN0YXRlLmZsb3dpbmcpO1xuICBpZiAoc3RhdGUuZmxvd2luZykge1xuICAgIGRvIHtcbiAgICAgIHZhciBjaHVuayA9IHN0cmVhbS5yZWFkKCk7XG4gICAgfSB3aGlsZSAobnVsbCAhPT0gY2h1bmsgJiYgc3RhdGUuZmxvd2luZyk7XG4gIH1cbn1cblxuLy8gd3JhcCBhbiBvbGQtc3R5bGUgc3RyZWFtIGFzIHRoZSBhc3luYyBkYXRhIHNvdXJjZS5cbi8vIFRoaXMgaXMgKm5vdCogcGFydCBvZiB0aGUgcmVhZGFibGUgc3RyZWFtIGludGVyZmFjZS5cbi8vIEl0IGlzIGFuIHVnbHkgdW5mb3J0dW5hdGUgbWVzcyBvZiBoaXN0b3J5LlxuUmVhZGFibGUucHJvdG90eXBlLndyYXAgPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIHBhdXNlZCA9IGZhbHNlO1xuXG4gIHZhciBzZWxmID0gdGhpcztcbiAgc3RyZWFtLm9uKCdlbmQnLCBmdW5jdGlvbigpIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBlbmQnKTtcbiAgICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhc3RhdGUuZW5kZWQpIHtcbiAgICAgIHZhciBjaHVuayA9IHN0YXRlLmRlY29kZXIuZW5kKCk7XG4gICAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKVxuICAgICAgICBzZWxmLnB1c2goY2h1bmspO1xuICAgIH1cblxuICAgIHNlbGYucHVzaChudWxsKTtcbiAgfSk7XG5cbiAgc3RyZWFtLm9uKCdkYXRhJywgZnVuY3Rpb24oY2h1bmspIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBkYXRhJyk7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIpXG4gICAgICBjaHVuayA9IHN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO1xuXG4gICAgLy8gZG9uJ3Qgc2tpcCBvdmVyIGZhbHN5IHZhbHVlcyBpbiBvYmplY3RNb2RlXG4gICAgaWYgKHN0YXRlLm9iamVjdE1vZGUgJiYgKGNodW5rID09PSBudWxsIHx8IGNodW5rID09PSB1bmRlZmluZWQpKVxuICAgICAgcmV0dXJuO1xuICAgIGVsc2UgaWYgKCFzdGF0ZS5vYmplY3RNb2RlICYmICghY2h1bmsgfHwgIWNodW5rLmxlbmd0aCkpXG4gICAgICByZXR1cm47XG5cbiAgICB2YXIgcmV0ID0gc2VsZi5wdXNoKGNodW5rKTtcbiAgICBpZiAoIXJldCkge1xuICAgICAgcGF1c2VkID0gdHJ1ZTtcbiAgICAgIHN0cmVhbS5wYXVzZSgpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gcHJveHkgYWxsIHRoZSBvdGhlciBtZXRob2RzLlxuICAvLyBpbXBvcnRhbnQgd2hlbiB3cmFwcGluZyBmaWx0ZXJzIGFuZCBkdXBsZXhlcy5cbiAgZm9yICh2YXIgaSBpbiBzdHJlYW0pIHtcbiAgICBpZiAodGhpc1tpXSA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBzdHJlYW1baV0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRoaXNbaV0gPSBmdW5jdGlvbihtZXRob2QpIHsgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gc3RyZWFtW21ldGhvZF0uYXBwbHkoc3RyZWFtLCBhcmd1bWVudHMpO1xuICAgICAgfTsgfShpKTtcbiAgICB9XG4gIH1cblxuICAvLyBwcm94eSBjZXJ0YWluIGltcG9ydGFudCBldmVudHMuXG4gIHZhciBldmVudHMgPSBbJ2Vycm9yJywgJ2Nsb3NlJywgJ2Rlc3Ryb3knLCAncGF1c2UnLCAncmVzdW1lJ107XG4gIGZvckVhY2goZXZlbnRzLCBmdW5jdGlvbihldikge1xuICAgIHN0cmVhbS5vbihldiwgc2VsZi5lbWl0LmJpbmQoc2VsZiwgZXYpKTtcbiAgfSk7XG5cbiAgLy8gd2hlbiB3ZSB0cnkgdG8gY29uc3VtZSBzb21lIG1vcmUgYnl0ZXMsIHNpbXBseSB1bnBhdXNlIHRoZVxuICAvLyB1bmRlcmx5aW5nIHN0cmVhbS5cbiAgc2VsZi5fcmVhZCA9IGZ1bmN0aW9uKG4pIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBfcmVhZCcsIG4pO1xuICAgIGlmIChwYXVzZWQpIHtcbiAgICAgIHBhdXNlZCA9IGZhbHNlO1xuICAgICAgc3RyZWFtLnJlc3VtZSgpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gc2VsZjtcbn07XG5cblxuLy8gZXhwb3NlZCBmb3IgdGVzdGluZyBwdXJwb3NlcyBvbmx5LlxuUmVhZGFibGUuX2Zyb21MaXN0ID0gZnJvbUxpc3Q7XG5cbi8vIFBsdWNrIG9mZiBuIGJ5dGVzIGZyb20gYW4gYXJyYXkgb2YgYnVmZmVycy5cbi8vIExlbmd0aCBpcyB0aGUgY29tYmluZWQgbGVuZ3RocyBvZiBhbGwgdGhlIGJ1ZmZlcnMgaW4gdGhlIGxpc3QuXG5mdW5jdGlvbiBmcm9tTGlzdChuLCBzdGF0ZSkge1xuICB2YXIgbGlzdCA9IHN0YXRlLmJ1ZmZlcjtcbiAgdmFyIGxlbmd0aCA9IHN0YXRlLmxlbmd0aDtcbiAgdmFyIHN0cmluZ01vZGUgPSAhIXN0YXRlLmRlY29kZXI7XG4gIHZhciBvYmplY3RNb2RlID0gISFzdGF0ZS5vYmplY3RNb2RlO1xuICB2YXIgcmV0O1xuXG4gIC8vIG5vdGhpbmcgaW4gdGhlIGxpc3QsIGRlZmluaXRlbHkgZW1wdHkuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMClcbiAgICByZXR1cm4gbnVsbDtcblxuICBpZiAobGVuZ3RoID09PSAwKVxuICAgIHJldCA9IG51bGw7XG4gIGVsc2UgaWYgKG9iamVjdE1vZGUpXG4gICAgcmV0ID0gbGlzdC5zaGlmdCgpO1xuICBlbHNlIGlmICghbiB8fCBuID49IGxlbmd0aCkge1xuICAgIC8vIHJlYWQgaXQgYWxsLCB0cnVuY2F0ZSB0aGUgYXJyYXkuXG4gICAgaWYgKHN0cmluZ01vZGUpXG4gICAgICByZXQgPSBsaXN0LmpvaW4oJycpO1xuICAgIGVsc2UgaWYgKGxpc3QubGVuZ3RoID09PSAxKVxuICAgICAgcmV0ID0gbGlzdFswXTtcbiAgICBlbHNlXG4gICAgICByZXQgPSBCdWZmZXIuY29uY2F0KGxpc3QsIGxlbmd0aCk7XG4gICAgbGlzdC5sZW5ndGggPSAwO1xuICB9IGVsc2Uge1xuICAgIC8vIHJlYWQganVzdCBzb21lIG9mIGl0LlxuICAgIGlmIChuIDwgbGlzdFswXS5sZW5ndGgpIHtcbiAgICAgIC8vIGp1c3QgdGFrZSBhIHBhcnQgb2YgdGhlIGZpcnN0IGxpc3QgaXRlbS5cbiAgICAgIC8vIHNsaWNlIGlzIHRoZSBzYW1lIGZvciBidWZmZXJzIGFuZCBzdHJpbmdzLlxuICAgICAgdmFyIGJ1ZiA9IGxpc3RbMF07XG4gICAgICByZXQgPSBidWYuc2xpY2UoMCwgbik7XG4gICAgICBsaXN0WzBdID0gYnVmLnNsaWNlKG4pO1xuICAgIH0gZWxzZSBpZiAobiA9PT0gbGlzdFswXS5sZW5ndGgpIHtcbiAgICAgIC8vIGZpcnN0IGxpc3QgaXMgYSBwZXJmZWN0IG1hdGNoXG4gICAgICByZXQgPSBsaXN0LnNoaWZ0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGNvbXBsZXggY2FzZS5cbiAgICAgIC8vIHdlIGhhdmUgZW5vdWdoIHRvIGNvdmVyIGl0LCBidXQgaXQgc3BhbnMgcGFzdCB0aGUgZmlyc3QgYnVmZmVyLlxuICAgICAgaWYgKHN0cmluZ01vZGUpXG4gICAgICAgIHJldCA9ICcnO1xuICAgICAgZWxzZVxuICAgICAgICByZXQgPSBuZXcgQnVmZmVyKG4pO1xuXG4gICAgICB2YXIgYyA9IDA7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGxpc3QubGVuZ3RoOyBpIDwgbCAmJiBjIDwgbjsgaSsrKSB7XG4gICAgICAgIHZhciBidWYgPSBsaXN0WzBdO1xuICAgICAgICB2YXIgY3B5ID0gTWF0aC5taW4obiAtIGMsIGJ1Zi5sZW5ndGgpO1xuXG4gICAgICAgIGlmIChzdHJpbmdNb2RlKVxuICAgICAgICAgIHJldCArPSBidWYuc2xpY2UoMCwgY3B5KTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIGJ1Zi5jb3B5KHJldCwgYywgMCwgY3B5KTtcblxuICAgICAgICBpZiAoY3B5IDwgYnVmLmxlbmd0aClcbiAgICAgICAgICBsaXN0WzBdID0gYnVmLnNsaWNlKGNweSk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBsaXN0LnNoaWZ0KCk7XG5cbiAgICAgICAgYyArPSBjcHk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gZW5kUmVhZGFibGUoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcblxuICAvLyBJZiB3ZSBnZXQgaGVyZSBiZWZvcmUgY29uc3VtaW5nIGFsbCB0aGUgYnl0ZXMsIHRoZW4gdGhhdCBpcyBhXG4gIC8vIGJ1ZyBpbiBub2RlLiAgU2hvdWxkIG5ldmVyIGhhcHBlbi5cbiAgaWYgKHN0YXRlLmxlbmd0aCA+IDApXG4gICAgdGhyb3cgbmV3IEVycm9yKCdlbmRSZWFkYWJsZSBjYWxsZWQgb24gbm9uLWVtcHR5IHN0cmVhbScpO1xuXG4gIGlmICghc3RhdGUuZW5kRW1pdHRlZCkge1xuICAgIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbiAgICBwcm9jZXNzTmV4dFRpY2soZW5kUmVhZGFibGVOVCwgc3RhdGUsIHN0cmVhbSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW5kUmVhZGFibGVOVChzdGF0ZSwgc3RyZWFtKSB7XG4gIC8vIENoZWNrIHRoYXQgd2UgZGlkbid0IGdldCBvbmUgbGFzdCB1bnNoaWZ0LlxuICBpZiAoIXN0YXRlLmVuZEVtaXR0ZWQgJiYgc3RhdGUubGVuZ3RoID09PSAwKSB7XG4gICAgc3RhdGUuZW5kRW1pdHRlZCA9IHRydWU7XG4gICAgc3RyZWFtLnJlYWRhYmxlID0gZmFsc2U7XG4gICAgc3RyZWFtLmVtaXQoJ2VuZCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZvckVhY2ggKHhzLCBmKSB7XG4gIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgZih4c1tpXSwgaSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5kZXhPZiAoeHMsIHgpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBpZiAoeHNbaV0gPT09IHgpIHJldHVybiBpO1xuICB9XG4gIHJldHVybiAtMTtcbn1cbiIsIi8vIGEgdHJhbnNmb3JtIHN0cmVhbSBpcyBhIHJlYWRhYmxlL3dyaXRhYmxlIHN0cmVhbSB3aGVyZSB5b3UgZG9cbi8vIHNvbWV0aGluZyB3aXRoIHRoZSBkYXRhLiAgU29tZXRpbWVzIGl0J3MgY2FsbGVkIGEgXCJmaWx0ZXJcIixcbi8vIGJ1dCB0aGF0J3Mgbm90IGEgZ3JlYXQgbmFtZSBmb3IgaXQsIHNpbmNlIHRoYXQgaW1wbGllcyBhIHRoaW5nIHdoZXJlXG4vLyBzb21lIGJpdHMgcGFzcyB0aHJvdWdoLCBhbmQgb3RoZXJzIGFyZSBzaW1wbHkgaWdub3JlZC4gIChUaGF0IHdvdWxkXG4vLyBiZSBhIHZhbGlkIGV4YW1wbGUgb2YgYSB0cmFuc2Zvcm0sIG9mIGNvdXJzZS4pXG4vL1xuLy8gV2hpbGUgdGhlIG91dHB1dCBpcyBjYXVzYWxseSByZWxhdGVkIHRvIHRoZSBpbnB1dCwgaXQncyBub3QgYVxuLy8gbmVjZXNzYXJpbHkgc3ltbWV0cmljIG9yIHN5bmNocm9ub3VzIHRyYW5zZm9ybWF0aW9uLiAgRm9yIGV4YW1wbGUsXG4vLyBhIHpsaWIgc3RyZWFtIG1pZ2h0IHRha2UgbXVsdGlwbGUgcGxhaW4tdGV4dCB3cml0ZXMoKSwgYW5kIHRoZW5cbi8vIGVtaXQgYSBzaW5nbGUgY29tcHJlc3NlZCBjaHVuayBzb21lIHRpbWUgaW4gdGhlIGZ1dHVyZS5cbi8vXG4vLyBIZXJlJ3MgaG93IHRoaXMgd29ya3M6XG4vL1xuLy8gVGhlIFRyYW5zZm9ybSBzdHJlYW0gaGFzIGFsbCB0aGUgYXNwZWN0cyBvZiB0aGUgcmVhZGFibGUgYW5kIHdyaXRhYmxlXG4vLyBzdHJlYW0gY2xhc3Nlcy4gIFdoZW4geW91IHdyaXRlKGNodW5rKSwgdGhhdCBjYWxscyBfd3JpdGUoY2h1bmssY2IpXG4vLyBpbnRlcm5hbGx5LCBhbmQgcmV0dXJucyBmYWxzZSBpZiB0aGVyZSdzIGEgbG90IG9mIHBlbmRpbmcgd3JpdGVzXG4vLyBidWZmZXJlZCB1cC4gIFdoZW4geW91IGNhbGwgcmVhZCgpLCB0aGF0IGNhbGxzIF9yZWFkKG4pIHVudGlsXG4vLyB0aGVyZSdzIGVub3VnaCBwZW5kaW5nIHJlYWRhYmxlIGRhdGEgYnVmZmVyZWQgdXAuXG4vL1xuLy8gSW4gYSB0cmFuc2Zvcm0gc3RyZWFtLCB0aGUgd3JpdHRlbiBkYXRhIGlzIHBsYWNlZCBpbiBhIGJ1ZmZlci4gIFdoZW5cbi8vIF9yZWFkKG4pIGlzIGNhbGxlZCwgaXQgdHJhbnNmb3JtcyB0aGUgcXVldWVkIHVwIGRhdGEsIGNhbGxpbmcgdGhlXG4vLyBidWZmZXJlZCBfd3JpdGUgY2IncyBhcyBpdCBjb25zdW1lcyBjaHVua3MuICBJZiBjb25zdW1pbmcgYSBzaW5nbGVcbi8vIHdyaXR0ZW4gY2h1bmsgd291bGQgcmVzdWx0IGluIG11bHRpcGxlIG91dHB1dCBjaHVua3MsIHRoZW4gdGhlIGZpcnN0XG4vLyBvdXRwdXR0ZWQgYml0IGNhbGxzIHRoZSByZWFkY2IsIGFuZCBzdWJzZXF1ZW50IGNodW5rcyBqdXN0IGdvIGludG9cbi8vIHRoZSByZWFkIGJ1ZmZlciwgYW5kIHdpbGwgY2F1c2UgaXQgdG8gZW1pdCAncmVhZGFibGUnIGlmIG5lY2Vzc2FyeS5cbi8vXG4vLyBUaGlzIHdheSwgYmFjay1wcmVzc3VyZSBpcyBhY3R1YWxseSBkZXRlcm1pbmVkIGJ5IHRoZSByZWFkaW5nIHNpZGUsXG4vLyBzaW5jZSBfcmVhZCBoYXMgdG8gYmUgY2FsbGVkIHRvIHN0YXJ0IHByb2Nlc3NpbmcgYSBuZXcgY2h1bmsuICBIb3dldmVyLFxuLy8gYSBwYXRob2xvZ2ljYWwgaW5mbGF0ZSB0eXBlIG9mIHRyYW5zZm9ybSBjYW4gY2F1c2UgZXhjZXNzaXZlIGJ1ZmZlcmluZ1xuLy8gaGVyZS4gIEZvciBleGFtcGxlLCBpbWFnaW5lIGEgc3RyZWFtIHdoZXJlIGV2ZXJ5IGJ5dGUgb2YgaW5wdXQgaXNcbi8vIGludGVycHJldGVkIGFzIGFuIGludGVnZXIgZnJvbSAwLTI1NSwgYW5kIHRoZW4gcmVzdWx0cyBpbiB0aGF0IG1hbnlcbi8vIGJ5dGVzIG9mIG91dHB1dC4gIFdyaXRpbmcgdGhlIDQgYnl0ZXMge2ZmLGZmLGZmLGZmfSB3b3VsZCByZXN1bHQgaW5cbi8vIDFrYiBvZiBkYXRhIGJlaW5nIG91dHB1dC4gIEluIHRoaXMgY2FzZSwgeW91IGNvdWxkIHdyaXRlIGEgdmVyeSBzbWFsbFxuLy8gYW1vdW50IG9mIGlucHV0LCBhbmQgZW5kIHVwIHdpdGggYSB2ZXJ5IGxhcmdlIGFtb3VudCBvZiBvdXRwdXQuICBJblxuLy8gc3VjaCBhIHBhdGhvbG9naWNhbCBpbmZsYXRpbmcgbWVjaGFuaXNtLCB0aGVyZSdkIGJlIG5vIHdheSB0byB0ZWxsXG4vLyB0aGUgc3lzdGVtIHRvIHN0b3AgZG9pbmcgdGhlIHRyYW5zZm9ybS4gIEEgc2luZ2xlIDRNQiB3cml0ZSBjb3VsZFxuLy8gY2F1c2UgdGhlIHN5c3RlbSB0byBydW4gb3V0IG9mIG1lbW9yeS5cbi8vXG4vLyBIb3dldmVyLCBldmVuIGluIHN1Y2ggYSBwYXRob2xvZ2ljYWwgY2FzZSwgb25seSBhIHNpbmdsZSB3cml0dGVuIGNodW5rXG4vLyB3b3VsZCBiZSBjb25zdW1lZCwgYW5kIHRoZW4gdGhlIHJlc3Qgd291bGQgd2FpdCAodW4tdHJhbnNmb3JtZWQpIHVudGlsXG4vLyB0aGUgcmVzdWx0cyBvZiB0aGUgcHJldmlvdXMgdHJhbnNmb3JtZWQgY2h1bmsgd2VyZSBjb25zdW1lZC5cblxuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFRyYW5zZm9ybTtcblxudmFyIER1cGxleCA9IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSgnY29yZS11dGlsLWlzJyk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG51dGlsLmluaGVyaXRzKFRyYW5zZm9ybSwgRHVwbGV4KTtcblxuXG5mdW5jdGlvbiBUcmFuc2Zvcm1TdGF0ZShzdHJlYW0pIHtcbiAgdGhpcy5hZnRlclRyYW5zZm9ybSA9IGZ1bmN0aW9uKGVyLCBkYXRhKSB7XG4gICAgcmV0dXJuIGFmdGVyVHJhbnNmb3JtKHN0cmVhbSwgZXIsIGRhdGEpO1xuICB9O1xuXG4gIHRoaXMubmVlZFRyYW5zZm9ybSA9IGZhbHNlO1xuICB0aGlzLnRyYW5zZm9ybWluZyA9IGZhbHNlO1xuICB0aGlzLndyaXRlY2IgPSBudWxsO1xuICB0aGlzLndyaXRlY2h1bmsgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBhZnRlclRyYW5zZm9ybShzdHJlYW0sIGVyLCBkYXRhKSB7XG4gIHZhciB0cyA9IHN0cmVhbS5fdHJhbnNmb3JtU3RhdGU7XG4gIHRzLnRyYW5zZm9ybWluZyA9IGZhbHNlO1xuXG4gIHZhciBjYiA9IHRzLndyaXRlY2I7XG5cbiAgaWYgKCFjYilcbiAgICByZXR1cm4gc3RyZWFtLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdubyB3cml0ZWNiIGluIFRyYW5zZm9ybSBjbGFzcycpKTtcblxuICB0cy53cml0ZWNodW5rID0gbnVsbDtcbiAgdHMud3JpdGVjYiA9IG51bGw7XG5cbiAgaWYgKGRhdGEgIT09IG51bGwgJiYgZGF0YSAhPT0gdW5kZWZpbmVkKVxuICAgIHN0cmVhbS5wdXNoKGRhdGEpO1xuXG4gIGlmIChjYilcbiAgICBjYihlcik7XG5cbiAgdmFyIHJzID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICBycy5yZWFkaW5nID0gZmFsc2U7XG4gIGlmIChycy5uZWVkUmVhZGFibGUgfHwgcnMubGVuZ3RoIDwgcnMuaGlnaFdhdGVyTWFyaykge1xuICAgIHN0cmVhbS5fcmVhZChycy5oaWdoV2F0ZXJNYXJrKTtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIFRyYW5zZm9ybShvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBUcmFuc2Zvcm0pKVxuICAgIHJldHVybiBuZXcgVHJhbnNmb3JtKG9wdGlvbnMpO1xuXG4gIER1cGxleC5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXG4gIHRoaXMuX3RyYW5zZm9ybVN0YXRlID0gbmV3IFRyYW5zZm9ybVN0YXRlKHRoaXMpO1xuXG4gIC8vIHdoZW4gdGhlIHdyaXRhYmxlIHNpZGUgZmluaXNoZXMsIHRoZW4gZmx1c2ggb3V0IGFueXRoaW5nIHJlbWFpbmluZy5cbiAgdmFyIHN0cmVhbSA9IHRoaXM7XG5cbiAgLy8gc3RhcnQgb3V0IGFza2luZyBmb3IgYSByZWFkYWJsZSBldmVudCBvbmNlIGRhdGEgaXMgdHJhbnNmb3JtZWQuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcblxuICAvLyB3ZSBoYXZlIGltcGxlbWVudGVkIHRoZSBfcmVhZCBtZXRob2QsIGFuZCBkb25lIHRoZSBvdGhlciB0aGluZ3NcbiAgLy8gdGhhdCBSZWFkYWJsZSB3YW50cyBiZWZvcmUgdGhlIGZpcnN0IF9yZWFkIGNhbGwsIHNvIHVuc2V0IHRoZVxuICAvLyBzeW5jIGd1YXJkIGZsYWcuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUuc3luYyA9IGZhbHNlO1xuXG4gIGlmIChvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLnRyYW5zZm9ybSA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgIHRoaXMuX3RyYW5zZm9ybSA9IG9wdGlvbnMudHJhbnNmb3JtO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmZsdXNoID09PSAnZnVuY3Rpb24nKVxuICAgICAgdGhpcy5fZmx1c2ggPSBvcHRpb25zLmZsdXNoO1xuICB9XG5cbiAgdGhpcy5vbmNlKCdwcmVmaW5pc2gnLCBmdW5jdGlvbigpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuX2ZsdXNoID09PSAnZnVuY3Rpb24nKVxuICAgICAgdGhpcy5fZmx1c2goZnVuY3Rpb24oZXIpIHtcbiAgICAgICAgZG9uZShzdHJlYW0sIGVyKTtcbiAgICAgIH0pO1xuICAgIGVsc2VcbiAgICAgIGRvbmUoc3RyZWFtKTtcbiAgfSk7XG59XG5cblRyYW5zZm9ybS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uKGNodW5rLCBlbmNvZGluZykge1xuICB0aGlzLl90cmFuc2Zvcm1TdGF0ZS5uZWVkVHJhbnNmb3JtID0gZmFsc2U7XG4gIHJldHVybiBEdXBsZXgucHJvdG90eXBlLnB1c2guY2FsbCh0aGlzLCBjaHVuaywgZW5jb2RpbmcpO1xufTtcblxuLy8gVGhpcyBpcyB0aGUgcGFydCB3aGVyZSB5b3UgZG8gc3R1ZmYhXG4vLyBvdmVycmlkZSB0aGlzIGZ1bmN0aW9uIGluIGltcGxlbWVudGF0aW9uIGNsYXNzZXMuXG4vLyAnY2h1bmsnIGlzIGFuIGlucHV0IGNodW5rLlxuLy9cbi8vIENhbGwgYHB1c2gobmV3Q2h1bmspYCB0byBwYXNzIGFsb25nIHRyYW5zZm9ybWVkIG91dHB1dFxuLy8gdG8gdGhlIHJlYWRhYmxlIHNpZGUuICBZb3UgbWF5IGNhbGwgJ3B1c2gnIHplcm8gb3IgbW9yZSB0aW1lcy5cbi8vXG4vLyBDYWxsIGBjYihlcnIpYCB3aGVuIHlvdSBhcmUgZG9uZSB3aXRoIHRoaXMgY2h1bmsuICBJZiB5b3UgcGFzc1xuLy8gYW4gZXJyb3IsIHRoZW4gdGhhdCdsbCBwdXQgdGhlIGh1cnQgb24gdGhlIHdob2xlIG9wZXJhdGlvbi4gIElmIHlvdVxuLy8gbmV2ZXIgY2FsbCBjYigpLCB0aGVuIHlvdSdsbCBuZXZlciBnZXQgYW5vdGhlciBjaHVuay5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdub3QgaW1wbGVtZW50ZWQnKTtcbn07XG5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcbiAgdHMud3JpdGVjYiA9IGNiO1xuICB0cy53cml0ZWNodW5rID0gY2h1bms7XG4gIHRzLndyaXRlZW5jb2RpbmcgPSBlbmNvZGluZztcbiAgaWYgKCF0cy50cmFuc2Zvcm1pbmcpIHtcbiAgICB2YXIgcnMgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICAgIGlmICh0cy5uZWVkVHJhbnNmb3JtIHx8XG4gICAgICAgIHJzLm5lZWRSZWFkYWJsZSB8fFxuICAgICAgICBycy5sZW5ndGggPCBycy5oaWdoV2F0ZXJNYXJrKVxuICAgICAgdGhpcy5fcmVhZChycy5oaWdoV2F0ZXJNYXJrKTtcbiAgfVxufTtcblxuLy8gRG9lc24ndCBtYXR0ZXIgd2hhdCB0aGUgYXJncyBhcmUgaGVyZS5cbi8vIF90cmFuc2Zvcm0gZG9lcyBhbGwgdGhlIHdvcmsuXG4vLyBUaGF0IHdlIGdvdCBoZXJlIG1lYW5zIHRoYXQgdGhlIHJlYWRhYmxlIHNpZGUgd2FudHMgbW9yZSBkYXRhLlxuVHJhbnNmb3JtLnByb3RvdHlwZS5fcmVhZCA9IGZ1bmN0aW9uKG4pIHtcbiAgdmFyIHRzID0gdGhpcy5fdHJhbnNmb3JtU3RhdGU7XG5cbiAgaWYgKHRzLndyaXRlY2h1bmsgIT09IG51bGwgJiYgdHMud3JpdGVjYiAmJiAhdHMudHJhbnNmb3JtaW5nKSB7XG4gICAgdHMudHJhbnNmb3JtaW5nID0gdHJ1ZTtcbiAgICB0aGlzLl90cmFuc2Zvcm0odHMud3JpdGVjaHVuaywgdHMud3JpdGVlbmNvZGluZywgdHMuYWZ0ZXJUcmFuc2Zvcm0pO1xuICB9IGVsc2Uge1xuICAgIC8vIG1hcmsgdGhhdCB3ZSBuZWVkIGEgdHJhbnNmb3JtLCBzbyB0aGF0IGFueSBkYXRhIHRoYXQgY29tZXMgaW5cbiAgICAvLyB3aWxsIGdldCBwcm9jZXNzZWQsIG5vdyB0aGF0IHdlJ3ZlIGFza2VkIGZvciBpdC5cbiAgICB0cy5uZWVkVHJhbnNmb3JtID0gdHJ1ZTtcbiAgfVxufTtcblxuXG5mdW5jdGlvbiBkb25lKHN0cmVhbSwgZXIpIHtcbiAgaWYgKGVyKVxuICAgIHJldHVybiBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG5cbiAgLy8gaWYgdGhlcmUncyBub3RoaW5nIGluIHRoZSB3cml0ZSBidWZmZXIsIHRoZW4gdGhhdCBtZWFuc1xuICAvLyB0aGF0IG5vdGhpbmcgbW9yZSB3aWxsIGV2ZXIgYmUgcHJvdmlkZWRcbiAgdmFyIHdzID0gc3RyZWFtLl93cml0YWJsZVN0YXRlO1xuICB2YXIgdHMgPSBzdHJlYW0uX3RyYW5zZm9ybVN0YXRlO1xuXG4gIGlmICh3cy5sZW5ndGgpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdjYWxsaW5nIHRyYW5zZm9ybSBkb25lIHdoZW4gd3MubGVuZ3RoICE9IDAnKTtcblxuICBpZiAodHMudHJhbnNmb3JtaW5nKVxuICAgIHRocm93IG5ldyBFcnJvcignY2FsbGluZyB0cmFuc2Zvcm0gZG9uZSB3aGVuIHN0aWxsIHRyYW5zZm9ybWluZycpO1xuXG4gIHJldHVybiBzdHJlYW0ucHVzaChudWxsKTtcbn1cbiIsIi8vIEEgYml0IHNpbXBsZXIgdGhhbiByZWFkYWJsZSBzdHJlYW1zLlxuLy8gSW1wbGVtZW50IGFuIGFzeW5jIC5fd3JpdGUoY2h1bmssIGVuY29kaW5nLCBjYiksIGFuZCBpdCdsbCBoYW5kbGUgYWxsXG4vLyB0aGUgZHJhaW4gZXZlbnQgZW1pc3Npb24gYW5kIGJ1ZmZlcmluZy5cblxuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdyaXRhYmxlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHByb2Nlc3NOZXh0VGljayA9IHJlcXVpcmUoJ3Byb2Nlc3MtbmV4dGljay1hcmdzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5Xcml0YWJsZS5Xcml0YWJsZVN0YXRlID0gV3JpdGFibGVTdGF0ZTtcblxuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSByZXF1aXJlKCdjb3JlLXV0aWwtaXMnKTtcbnV0aWwuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBpbnRlcm5hbFV0aWwgPSB7XG4gIGRlcHJlY2F0ZTogcmVxdWlyZSgndXRpbC1kZXByZWNhdGUnKVxufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBTdHJlYW07XG4oZnVuY3Rpb24gKCl7dHJ5e1xuICBTdHJlYW0gPSByZXF1aXJlKCdzdCcgKyAncmVhbScpO1xufWNhdGNoKF8pe31maW5hbGx5e1xuICBpZiAoIVN0cmVhbSlcbiAgICBTdHJlYW0gPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG59fSgpKVxuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG5cbnV0aWwuaW5oZXJpdHMoV3JpdGFibGUsIFN0cmVhbSk7XG5cbmZ1bmN0aW9uIG5vcCgpIHt9XG5cbmZ1bmN0aW9uIFdyaXRlUmVxKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdGhpcy5jaHVuayA9IGNodW5rO1xuICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7XG4gIHRoaXMuY2FsbGJhY2sgPSBjYjtcbiAgdGhpcy5uZXh0ID0gbnVsbDtcbn1cblxudmFyIER1cGxleDtcbmZ1bmN0aW9uIFdyaXRhYmxlU3RhdGUob3B0aW9ucywgc3RyZWFtKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgLy8gb2JqZWN0IHN0cmVhbSBmbGFnIHRvIGluZGljYXRlIHdoZXRoZXIgb3Igbm90IHRoaXMgc3RyZWFtXG4gIC8vIGNvbnRhaW5zIGJ1ZmZlcnMgb3Igb2JqZWN0cy5cbiAgdGhpcy5vYmplY3RNb2RlID0gISFvcHRpb25zLm9iamVjdE1vZGU7XG5cbiAgaWYgKHN0cmVhbSBpbnN0YW5jZW9mIER1cGxleClcbiAgICB0aGlzLm9iamVjdE1vZGUgPSB0aGlzLm9iamVjdE1vZGUgfHwgISFvcHRpb25zLndyaXRhYmxlT2JqZWN0TW9kZTtcblxuICAvLyB0aGUgcG9pbnQgYXQgd2hpY2ggd3JpdGUoKSBzdGFydHMgcmV0dXJuaW5nIGZhbHNlXG4gIC8vIE5vdGU6IDAgaXMgYSB2YWxpZCB2YWx1ZSwgbWVhbnMgdGhhdCB3ZSBhbHdheXMgcmV0dXJuIGZhbHNlIGlmXG4gIC8vIHRoZSBlbnRpcmUgYnVmZmVyIGlzIG5vdCBmbHVzaGVkIGltbWVkaWF0ZWx5IG9uIHdyaXRlKClcbiAgdmFyIGh3bSA9IG9wdGlvbnMuaGlnaFdhdGVyTWFyaztcbiAgdmFyIGRlZmF1bHRId20gPSB0aGlzLm9iamVjdE1vZGUgPyAxNiA6IDE2ICogMTAyNDtcbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gKGh3bSB8fCBod20gPT09IDApID8gaHdtIDogZGVmYXVsdEh3bTtcblxuICAvLyBjYXN0IHRvIGludHMuXG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IH5+dGhpcy5oaWdoV2F0ZXJNYXJrO1xuXG4gIHRoaXMubmVlZERyYWluID0gZmFsc2U7XG4gIC8vIGF0IHRoZSBzdGFydCBvZiBjYWxsaW5nIGVuZCgpXG4gIHRoaXMuZW5kaW5nID0gZmFsc2U7XG4gIC8vIHdoZW4gZW5kKCkgaGFzIGJlZW4gY2FsbGVkLCBhbmQgcmV0dXJuZWRcbiAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICAvLyB3aGVuICdmaW5pc2gnIGlzIGVtaXR0ZWRcbiAgdGhpcy5maW5pc2hlZCA9IGZhbHNlO1xuXG4gIC8vIHNob3VsZCB3ZSBkZWNvZGUgc3RyaW5ncyBpbnRvIGJ1ZmZlcnMgYmVmb3JlIHBhc3NpbmcgdG8gX3dyaXRlP1xuICAvLyB0aGlzIGlzIGhlcmUgc28gdGhhdCBzb21lIG5vZGUtY29yZSBzdHJlYW1zIGNhbiBvcHRpbWl6ZSBzdHJpbmdcbiAgLy8gaGFuZGxpbmcgYXQgYSBsb3dlciBsZXZlbC5cbiAgdmFyIG5vRGVjb2RlID0gb3B0aW9ucy5kZWNvZGVTdHJpbmdzID09PSBmYWxzZTtcbiAgdGhpcy5kZWNvZGVTdHJpbmdzID0gIW5vRGVjb2RlO1xuXG4gIC8vIENyeXB0byBpcyBraW5kIG9mIG9sZCBhbmQgY3J1c3R5LiAgSGlzdG9yaWNhbGx5LCBpdHMgZGVmYXVsdCBzdHJpbmdcbiAgLy8gZW5jb2RpbmcgaXMgJ2JpbmFyeScgc28gd2UgaGF2ZSB0byBtYWtlIHRoaXMgY29uZmlndXJhYmxlLlxuICAvLyBFdmVyeXRoaW5nIGVsc2UgaW4gdGhlIHVuaXZlcnNlIHVzZXMgJ3V0ZjgnLCB0aG91Z2guXG4gIHRoaXMuZGVmYXVsdEVuY29kaW5nID0gb3B0aW9ucy5kZWZhdWx0RW5jb2RpbmcgfHwgJ3V0ZjgnO1xuXG4gIC8vIG5vdCBhbiBhY3R1YWwgYnVmZmVyIHdlIGtlZXAgdHJhY2sgb2YsIGJ1dCBhIG1lYXN1cmVtZW50XG4gIC8vIG9mIGhvdyBtdWNoIHdlJ3JlIHdhaXRpbmcgdG8gZ2V0IHB1c2hlZCB0byBzb21lIHVuZGVybHlpbmdcbiAgLy8gc29ja2V0IG9yIGZpbGUuXG4gIHRoaXMubGVuZ3RoID0gMDtcblxuICAvLyBhIGZsYWcgdG8gc2VlIHdoZW4gd2UncmUgaW4gdGhlIG1pZGRsZSBvZiBhIHdyaXRlLlxuICB0aGlzLndyaXRpbmcgPSBmYWxzZTtcblxuICAvLyB3aGVuIHRydWUgYWxsIHdyaXRlcyB3aWxsIGJlIGJ1ZmZlcmVkIHVudGlsIC51bmNvcmsoKSBjYWxsXG4gIHRoaXMuY29ya2VkID0gMDtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBvbndyaXRlIGNiIGlzIGNhbGxlZCBpbW1lZGlhdGVseSxcbiAgLy8gb3Igb24gYSBsYXRlciB0aWNrLiAgV2Ugc2V0IHRoaXMgdG8gdHJ1ZSBhdCBmaXJzdCwgYmVjYXVzZSBhbnlcbiAgLy8gYWN0aW9ucyB0aGF0IHNob3VsZG4ndCBoYXBwZW4gdW50aWwgXCJsYXRlclwiIHNob3VsZCBnZW5lcmFsbHkgYWxzb1xuICAvLyBub3QgaGFwcGVuIGJlZm9yZSB0aGUgZmlyc3Qgd3JpdGUgY2FsbC5cbiAgdGhpcy5zeW5jID0gdHJ1ZTtcblxuICAvLyBhIGZsYWcgdG8ga25vdyBpZiB3ZSdyZSBwcm9jZXNzaW5nIHByZXZpb3VzbHkgYnVmZmVyZWQgaXRlbXMsIHdoaWNoXG4gIC8vIG1heSBjYWxsIHRoZSBfd3JpdGUoKSBjYWxsYmFjayBpbiB0aGUgc2FtZSB0aWNrLCBzbyB0aGF0IHdlIGRvbid0XG4gIC8vIGVuZCB1cCBpbiBhbiBvdmVybGFwcGVkIG9ud3JpdGUgc2l0dWF0aW9uLlxuICB0aGlzLmJ1ZmZlclByb2Nlc3NpbmcgPSBmYWxzZTtcblxuICAvLyB0aGUgY2FsbGJhY2sgdGhhdCdzIHBhc3NlZCB0byBfd3JpdGUoY2h1bmssY2IpXG4gIHRoaXMub253cml0ZSA9IGZ1bmN0aW9uKGVyKSB7XG4gICAgb253cml0ZShzdHJlYW0sIGVyKTtcbiAgfTtcblxuICAvLyB0aGUgY2FsbGJhY2sgdGhhdCB0aGUgdXNlciBzdXBwbGllcyB0byB3cml0ZShjaHVuayxlbmNvZGluZyxjYilcbiAgdGhpcy53cml0ZWNiID0gbnVsbDtcblxuICAvLyB0aGUgYW1vdW50IHRoYXQgaXMgYmVpbmcgd3JpdHRlbiB3aGVuIF93cml0ZSBpcyBjYWxsZWQuXG4gIHRoaXMud3JpdGVsZW4gPSAwO1xuXG4gIHRoaXMuYnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcbiAgdGhpcy5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcblxuICAvLyBudW1iZXIgb2YgcGVuZGluZyB1c2VyLXN1cHBsaWVkIHdyaXRlIGNhbGxiYWNrc1xuICAvLyB0aGlzIG11c3QgYmUgMCBiZWZvcmUgJ2ZpbmlzaCcgY2FuIGJlIGVtaXR0ZWRcbiAgdGhpcy5wZW5kaW5nY2IgPSAwO1xuXG4gIC8vIGVtaXQgcHJlZmluaXNoIGlmIHRoZSBvbmx5IHRoaW5nIHdlJ3JlIHdhaXRpbmcgZm9yIGlzIF93cml0ZSBjYnNcbiAgLy8gVGhpcyBpcyByZWxldmFudCBmb3Igc3luY2hyb25vdXMgVHJhbnNmb3JtIHN0cmVhbXNcbiAgdGhpcy5wcmVmaW5pc2hlZCA9IGZhbHNlO1xuXG4gIC8vIFRydWUgaWYgdGhlIGVycm9yIHdhcyBhbHJlYWR5IGVtaXR0ZWQgYW5kIHNob3VsZCBub3QgYmUgdGhyb3duIGFnYWluXG4gIHRoaXMuZXJyb3JFbWl0dGVkID0gZmFsc2U7XG59XG5cbldyaXRhYmxlU3RhdGUucHJvdG90eXBlLmdldEJ1ZmZlciA9IGZ1bmN0aW9uIHdyaXRhYmxlU3RhdGVHZXRCdWZmZXIoKSB7XG4gIHZhciBjdXJyZW50ID0gdGhpcy5idWZmZXJlZFJlcXVlc3Q7XG4gIHZhciBvdXQgPSBbXTtcbiAgd2hpbGUgKGN1cnJlbnQpIHtcbiAgICBvdXQucHVzaChjdXJyZW50KTtcbiAgICBjdXJyZW50ID0gY3VycmVudC5uZXh0O1xuICB9XG4gIHJldHVybiBvdXQ7XG59O1xuXG4oZnVuY3Rpb24gKCl7dHJ5IHtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZVN0YXRlLnByb3RvdHlwZSwgJ2J1ZmZlcicsIHtcbiAgZ2V0OiBpbnRlcm5hbFV0aWwuZGVwcmVjYXRlKGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmdldEJ1ZmZlcigpO1xuICB9LCAnX3dyaXRhYmxlU3RhdGUuYnVmZmVyIGlzIGRlcHJlY2F0ZWQuIFVzZSBfd3JpdGFibGVTdGF0ZS5nZXRCdWZmZXIgJyArXG4gICAgICdpbnN0ZWFkLicpXG59KTtcbn1jYXRjaChfKXt9fSgpKTtcblxuXG52YXIgRHVwbGV4O1xuZnVuY3Rpb24gV3JpdGFibGUob3B0aW9ucykge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIC8vIFdyaXRhYmxlIGN0b3IgaXMgYXBwbGllZCB0byBEdXBsZXhlcywgdGhvdWdoIHRoZXkncmUgbm90XG4gIC8vIGluc3RhbmNlb2YgV3JpdGFibGUsIHRoZXkncmUgaW5zdGFuY2VvZiBSZWFkYWJsZS5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFdyaXRhYmxlKSAmJiAhKHRoaXMgaW5zdGFuY2VvZiBEdXBsZXgpKVxuICAgIHJldHVybiBuZXcgV3JpdGFibGUob3B0aW9ucyk7XG5cbiAgdGhpcy5fd3JpdGFibGVTdGF0ZSA9IG5ldyBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHRoaXMpO1xuXG4gIC8vIGxlZ2FjeS5cbiAgdGhpcy53cml0YWJsZSA9IHRydWU7XG5cbiAgaWYgKG9wdGlvbnMpIHtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMud3JpdGUgPT09ICdmdW5jdGlvbicpXG4gICAgICB0aGlzLl93cml0ZSA9IG9wdGlvbnMud3JpdGU7XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMud3JpdGV2ID09PSAnZnVuY3Rpb24nKVxuICAgICAgdGhpcy5fd3JpdGV2ID0gb3B0aW9ucy53cml0ZXY7XG4gIH1cblxuICBTdHJlYW0uY2FsbCh0aGlzKTtcbn1cblxuLy8gT3RoZXJ3aXNlIHBlb3BsZSBjYW4gcGlwZSBXcml0YWJsZSBzdHJlYW1zLCB3aGljaCBpcyBqdXN0IHdyb25nLlxuV3JpdGFibGUucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignQ2Fubm90IHBpcGUuIE5vdCByZWFkYWJsZS4nKSk7XG59O1xuXG5cbmZ1bmN0aW9uIHdyaXRlQWZ0ZXJFbmQoc3RyZWFtLCBjYikge1xuICB2YXIgZXIgPSBuZXcgRXJyb3IoJ3dyaXRlIGFmdGVyIGVuZCcpO1xuICAvLyBUT0RPOiBkZWZlciBlcnJvciBldmVudHMgY29uc2lzdGVudGx5IGV2ZXJ5d2hlcmUsIG5vdCBqdXN0IHRoZSBjYlxuICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gIHByb2Nlc3NOZXh0VGljayhjYiwgZXIpO1xufVxuXG4vLyBJZiB3ZSBnZXQgc29tZXRoaW5nIHRoYXQgaXMgbm90IGEgYnVmZmVyLCBzdHJpbmcsIG51bGwsIG9yIHVuZGVmaW5lZCxcbi8vIGFuZCB3ZSdyZSBub3QgaW4gb2JqZWN0TW9kZSwgdGhlbiB0aGF0J3MgYW4gZXJyb3IuXG4vLyBPdGhlcndpc2Ugc3RyZWFtIGNodW5rcyBhcmUgYWxsIGNvbnNpZGVyZWQgdG8gYmUgb2YgbGVuZ3RoPTEsIGFuZCB0aGVcbi8vIHdhdGVybWFya3MgZGV0ZXJtaW5lIGhvdyBtYW55IG9iamVjdHMgdG8ga2VlcCBpbiB0aGUgYnVmZmVyLCByYXRoZXIgdGhhblxuLy8gaG93IG1hbnkgYnl0ZXMgb3IgY2hhcmFjdGVycy5cbmZ1bmN0aW9uIHZhbGlkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGNiKSB7XG4gIHZhciB2YWxpZCA9IHRydWU7XG5cbiAgaWYgKCEoQnVmZmVyLmlzQnVmZmVyKGNodW5rKSkgJiZcbiAgICAgIHR5cGVvZiBjaHVuayAhPT0gJ3N0cmluZycgJiZcbiAgICAgIGNodW5rICE9PSBudWxsICYmXG4gICAgICBjaHVuayAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAhc3RhdGUub2JqZWN0TW9kZSkge1xuICAgIHZhciBlciA9IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbm9uLXN0cmluZy9idWZmZXIgY2h1bmsnKTtcbiAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gICAgcHJvY2Vzc05leHRUaWNrKGNiLCBlcik7XG4gICAgdmFsaWQgPSBmYWxzZTtcbiAgfVxuICByZXR1cm4gdmFsaWQ7XG59XG5cbldyaXRhYmxlLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcbiAgdmFyIHJldCA9IGZhbHNlO1xuXG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuXG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoY2h1bmspKVxuICAgIGVuY29kaW5nID0gJ2J1ZmZlcic7XG4gIGVsc2UgaWYgKCFlbmNvZGluZylcbiAgICBlbmNvZGluZyA9IHN0YXRlLmRlZmF1bHRFbmNvZGluZztcblxuICBpZiAodHlwZW9mIGNiICE9PSAnZnVuY3Rpb24nKVxuICAgIGNiID0gbm9wO1xuXG4gIGlmIChzdGF0ZS5lbmRlZClcbiAgICB3cml0ZUFmdGVyRW5kKHRoaXMsIGNiKTtcbiAgZWxzZSBpZiAodmFsaWRDaHVuayh0aGlzLCBzdGF0ZSwgY2h1bmssIGNiKSkge1xuICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgIHJldCA9IHdyaXRlT3JCdWZmZXIodGhpcywgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgY2IpO1xuICB9XG5cbiAgcmV0dXJuIHJldDtcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5jb3JrID0gZnVuY3Rpb24oKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG5cbiAgc3RhdGUuY29ya2VkKys7XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUudW5jb3JrID0gZnVuY3Rpb24oKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG5cbiAgaWYgKHN0YXRlLmNvcmtlZCkge1xuICAgIHN0YXRlLmNvcmtlZC0tO1xuXG4gICAgaWYgKCFzdGF0ZS53cml0aW5nICYmXG4gICAgICAgICFzdGF0ZS5jb3JrZWQgJiZcbiAgICAgICAgIXN0YXRlLmZpbmlzaGVkICYmXG4gICAgICAgICFzdGF0ZS5idWZmZXJQcm9jZXNzaW5nICYmXG4gICAgICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdClcbiAgICAgIGNsZWFyQnVmZmVyKHRoaXMsIHN0YXRlKTtcbiAgfVxufTtcblxuV3JpdGFibGUucHJvdG90eXBlLnNldERlZmF1bHRFbmNvZGluZyA9IGZ1bmN0aW9uIHNldERlZmF1bHRFbmNvZGluZyhlbmNvZGluZykge1xuICAvLyBub2RlOjpQYXJzZUVuY29kaW5nKCkgcmVxdWlyZXMgbG93ZXIgY2FzZS5cbiAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycpXG4gICAgZW5jb2RpbmcgPSBlbmNvZGluZy50b0xvd2VyQ2FzZSgpO1xuICBpZiAoIShbJ2hleCcsICd1dGY4JywgJ3V0Zi04JywgJ2FzY2lpJywgJ2JpbmFyeScsICdiYXNlNjQnLFxuJ3VjczInLCAndWNzLTInLCd1dGYxNmxlJywgJ3V0Zi0xNmxlJywgJ3JhdyddXG4uaW5kZXhPZigoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKSkgPiAtMSkpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKTtcbiAgdGhpcy5fd3JpdGFibGVTdGF0ZS5kZWZhdWx0RW5jb2RpbmcgPSBlbmNvZGluZztcbn07XG5cbmZ1bmN0aW9uIGRlY29kZUNodW5rKHN0YXRlLCBjaHVuaywgZW5jb2RpbmcpIHtcbiAgaWYgKCFzdGF0ZS5vYmplY3RNb2RlICYmXG4gICAgICBzdGF0ZS5kZWNvZGVTdHJpbmdzICE9PSBmYWxzZSAmJlxuICAgICAgdHlwZW9mIGNodW5rID09PSAnc3RyaW5nJykge1xuICAgIGNodW5rID0gbmV3IEJ1ZmZlcihjaHVuaywgZW5jb2RpbmcpO1xuICB9XG4gIHJldHVybiBjaHVuaztcbn1cblxuLy8gaWYgd2UncmUgYWxyZWFkeSB3cml0aW5nIHNvbWV0aGluZywgdGhlbiBqdXN0IHB1dCB0aGlzXG4vLyBpbiB0aGUgcXVldWUsIGFuZCB3YWl0IG91ciB0dXJuLiAgT3RoZXJ3aXNlLCBjYWxsIF93cml0ZVxuLy8gSWYgd2UgcmV0dXJuIGZhbHNlLCB0aGVuIHdlIG5lZWQgYSBkcmFpbiBldmVudCwgc28gc2V0IHRoYXQgZmxhZy5cbmZ1bmN0aW9uIHdyaXRlT3JCdWZmZXIoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjaHVuayA9IGRlY29kZUNodW5rKHN0YXRlLCBjaHVuaywgZW5jb2RpbmcpO1xuXG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoY2h1bmspKVxuICAgIGVuY29kaW5nID0gJ2J1ZmZlcic7XG4gIHZhciBsZW4gPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcblxuICBzdGF0ZS5sZW5ndGggKz0gbGVuO1xuXG4gIHZhciByZXQgPSBzdGF0ZS5sZW5ndGggPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrO1xuICAvLyB3ZSBtdXN0IGVuc3VyZSB0aGF0IHByZXZpb3VzIG5lZWREcmFpbiB3aWxsIG5vdCBiZSByZXNldCB0byBmYWxzZS5cbiAgaWYgKCFyZXQpXG4gICAgc3RhdGUubmVlZERyYWluID0gdHJ1ZTtcblxuICBpZiAoc3RhdGUud3JpdGluZyB8fCBzdGF0ZS5jb3JrZWQpIHtcbiAgICB2YXIgbGFzdCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG5ldyBXcml0ZVJlcShjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgICBpZiAobGFzdCkge1xuICAgICAgbGFzdC5uZXh0ID0gc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0ID0gc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBmYWxzZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgd3JpdGV2LCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgc3RhdGUud3JpdGVsZW4gPSBsZW47XG4gIHN0YXRlLndyaXRlY2IgPSBjYjtcbiAgc3RhdGUud3JpdGluZyA9IHRydWU7XG4gIHN0YXRlLnN5bmMgPSB0cnVlO1xuICBpZiAod3JpdGV2KVxuICAgIHN0cmVhbS5fd3JpdGV2KGNodW5rLCBzdGF0ZS5vbndyaXRlKTtcbiAgZWxzZVxuICAgIHN0cmVhbS5fd3JpdGUoY2h1bmssIGVuY29kaW5nLCBzdGF0ZS5vbndyaXRlKTtcbiAgc3RhdGUuc3luYyA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBvbndyaXRlRXJyb3Ioc3RyZWFtLCBzdGF0ZSwgc3luYywgZXIsIGNiKSB7XG4gIC0tc3RhdGUucGVuZGluZ2NiO1xuICBpZiAoc3luYylcbiAgICBwcm9jZXNzTmV4dFRpY2soY2IsIGVyKTtcbiAgZWxzZVxuICAgIGNiKGVyKTtcblxuICBzdHJlYW0uX3dyaXRhYmxlU3RhdGUuZXJyb3JFbWl0dGVkID0gdHJ1ZTtcbiAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xufVxuXG5mdW5jdGlvbiBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpIHtcbiAgc3RhdGUud3JpdGluZyA9IGZhbHNlO1xuICBzdGF0ZS53cml0ZWNiID0gbnVsbDtcbiAgc3RhdGUubGVuZ3RoIC09IHN0YXRlLndyaXRlbGVuO1xuICBzdGF0ZS53cml0ZWxlbiA9IDA7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGUoc3RyZWFtLCBlcikge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3dyaXRhYmxlU3RhdGU7XG4gIHZhciBzeW5jID0gc3RhdGUuc3luYztcbiAgdmFyIGNiID0gc3RhdGUud3JpdGVjYjtcblxuICBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpO1xuXG4gIGlmIChlcilcbiAgICBvbndyaXRlRXJyb3Ioc3RyZWFtLCBzdGF0ZSwgc3luYywgZXIsIGNiKTtcbiAgZWxzZSB7XG4gICAgLy8gQ2hlY2sgaWYgd2UncmUgYWN0dWFsbHkgcmVhZHkgdG8gZmluaXNoLCBidXQgZG9uJ3QgZW1pdCB5ZXRcbiAgICB2YXIgZmluaXNoZWQgPSBuZWVkRmluaXNoKHN0YXRlKTtcblxuICAgIGlmICghZmluaXNoZWQgJiZcbiAgICAgICAgIXN0YXRlLmNvcmtlZCAmJlxuICAgICAgICAhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyAmJlxuICAgICAgICBzdGF0ZS5idWZmZXJlZFJlcXVlc3QpIHtcbiAgICAgIGNsZWFyQnVmZmVyKHN0cmVhbSwgc3RhdGUpO1xuICAgIH1cblxuICAgIGlmIChzeW5jKSB7XG4gICAgICBwcm9jZXNzTmV4dFRpY2soYWZ0ZXJXcml0ZSwgc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhZnRlcldyaXRlKHN0cmVhbSwgc3RhdGUsIGZpbmlzaGVkLCBjYikge1xuICBpZiAoIWZpbmlzaGVkKVxuICAgIG9ud3JpdGVEcmFpbihzdHJlYW0sIHN0YXRlKTtcbiAgc3RhdGUucGVuZGluZ2NiLS07XG4gIGNiKCk7XG4gIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpO1xufVxuXG4vLyBNdXN0IGZvcmNlIGNhbGxiYWNrIHRvIGJlIGNhbGxlZCBvbiBuZXh0VGljaywgc28gdGhhdCB3ZSBkb24ndFxuLy8gZW1pdCAnZHJhaW4nIGJlZm9yZSB0aGUgd3JpdGUoKSBjb25zdW1lciBnZXRzIHRoZSAnZmFsc2UnIHJldHVyblxuLy8gdmFsdWUsIGFuZCBoYXMgYSBjaGFuY2UgdG8gYXR0YWNoIGEgJ2RyYWluJyBsaXN0ZW5lci5cbmZ1bmN0aW9uIG9ud3JpdGVEcmFpbihzdHJlYW0sIHN0YXRlKSB7XG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUubmVlZERyYWluKSB7XG4gICAgc3RhdGUubmVlZERyYWluID0gZmFsc2U7XG4gICAgc3RyZWFtLmVtaXQoJ2RyYWluJyk7XG4gIH1cbn1cblxuXG4vLyBpZiB0aGVyZSdzIHNvbWV0aGluZyBpbiB0aGUgYnVmZmVyIHdhaXRpbmcsIHRoZW4gcHJvY2VzcyBpdFxuZnVuY3Rpb24gY2xlYXJCdWZmZXIoc3RyZWFtLCBzdGF0ZSkge1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gdHJ1ZTtcbiAgdmFyIGVudHJ5ID0gc3RhdGUuYnVmZmVyZWRSZXF1ZXN0O1xuXG4gIGlmIChzdHJlYW0uX3dyaXRldiAmJiBlbnRyeSAmJiBlbnRyeS5uZXh0KSB7XG4gICAgLy8gRmFzdCBjYXNlLCB3cml0ZSBldmVyeXRoaW5nIHVzaW5nIF93cml0ZXYoKVxuICAgIHZhciBidWZmZXIgPSBbXTtcbiAgICB2YXIgY2JzID0gW107XG4gICAgd2hpbGUgKGVudHJ5KSB7XG4gICAgICBjYnMucHVzaChlbnRyeS5jYWxsYmFjayk7XG4gICAgICBidWZmZXIucHVzaChlbnRyeSk7XG4gICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7XG4gICAgfVxuXG4gICAgLy8gY291bnQgdGhlIG9uZSB3ZSBhcmUgYWRkaW5nLCBhcyB3ZWxsLlxuICAgIC8vIFRPRE8oaXNhYWNzKSBjbGVhbiB0aGlzIHVwXG4gICAgc3RhdGUucGVuZGluZ2NiKys7XG4gICAgc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCB0cnVlLCBzdGF0ZS5sZW5ndGgsIGJ1ZmZlciwgJycsIGZ1bmN0aW9uKGVycikge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgc3RhdGUucGVuZGluZ2NiLS07XG4gICAgICAgIGNic1tpXShlcnIpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gQ2xlYXIgYnVmZmVyXG4gIH0gZWxzZSB7XG4gICAgLy8gU2xvdyBjYXNlLCB3cml0ZSBjaHVua3Mgb25lLWJ5LW9uZVxuICAgIHdoaWxlIChlbnRyeSkge1xuICAgICAgdmFyIGNodW5rID0gZW50cnkuY2h1bms7XG4gICAgICB2YXIgZW5jb2RpbmcgPSBlbnRyeS5lbmNvZGluZztcbiAgICAgIHZhciBjYiA9IGVudHJ5LmNhbGxiYWNrO1xuICAgICAgdmFyIGxlbiA9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuXG4gICAgICBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIGZhbHNlLCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpO1xuICAgICAgZW50cnkgPSBlbnRyeS5uZXh0O1xuICAgICAgLy8gaWYgd2UgZGlkbid0IGNhbGwgdGhlIG9ud3JpdGUgaW1tZWRpYXRlbHksIHRoZW5cbiAgICAgIC8vIGl0IG1lYW5zIHRoYXQgd2UgbmVlZCB0byB3YWl0IHVudGlsIGl0IGRvZXMuXG4gICAgICAvLyBhbHNvLCB0aGF0IG1lYW5zIHRoYXQgdGhlIGNodW5rIGFuZCBjYiBhcmUgY3VycmVudGx5XG4gICAgICAvLyBiZWluZyBwcm9jZXNzZWQsIHNvIG1vdmUgdGhlIGJ1ZmZlciBjb3VudGVyIHBhc3QgdGhlbS5cbiAgICAgIGlmIChzdGF0ZS53cml0aW5nKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlbnRyeSA9PT0gbnVsbClcbiAgICAgIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuICB9XG4gIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9IGVudHJ5O1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gZmFsc2U7XG59XG5cbldyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGNiKG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJykpO1xufTtcblxuV3JpdGFibGUucHJvdG90eXBlLl93cml0ZXYgPSBudWxsO1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuXG4gIGlmICh0eXBlb2YgY2h1bmsgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGNodW5rO1xuICAgIGNodW5rID0gbnVsbDtcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBlbmNvZGluZztcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH1cblxuICBpZiAoY2h1bmsgIT09IG51bGwgJiYgY2h1bmsgIT09IHVuZGVmaW5lZClcbiAgICB0aGlzLndyaXRlKGNodW5rLCBlbmNvZGluZyk7XG5cbiAgLy8gLmVuZCgpIGZ1bGx5IHVuY29ya3NcbiAgaWYgKHN0YXRlLmNvcmtlZCkge1xuICAgIHN0YXRlLmNvcmtlZCA9IDE7XG4gICAgdGhpcy51bmNvcmsoKTtcbiAgfVxuXG4gIC8vIGlnbm9yZSB1bm5lY2Vzc2FyeSBlbmQoKSBjYWxscy5cbiAgaWYgKCFzdGF0ZS5lbmRpbmcgJiYgIXN0YXRlLmZpbmlzaGVkKVxuICAgIGVuZFdyaXRhYmxlKHRoaXMsIHN0YXRlLCBjYik7XG59O1xuXG5cbmZ1bmN0aW9uIG5lZWRGaW5pc2goc3RhdGUpIHtcbiAgcmV0dXJuIChzdGF0ZS5lbmRpbmcgJiZcbiAgICAgICAgICBzdGF0ZS5sZW5ndGggPT09IDAgJiZcbiAgICAgICAgICBzdGF0ZS5idWZmZXJlZFJlcXVlc3QgPT09IG51bGwgJiZcbiAgICAgICAgICAhc3RhdGUuZmluaXNoZWQgJiZcbiAgICAgICAgICAhc3RhdGUud3JpdGluZyk7XG59XG5cbmZ1bmN0aW9uIHByZWZpbmlzaChzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucHJlZmluaXNoZWQpIHtcbiAgICBzdGF0ZS5wcmVmaW5pc2hlZCA9IHRydWU7XG4gICAgc3RyZWFtLmVtaXQoJ3ByZWZpbmlzaCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpIHtcbiAgdmFyIG5lZWQgPSBuZWVkRmluaXNoKHN0YXRlKTtcbiAgaWYgKG5lZWQpIHtcbiAgICBpZiAoc3RhdGUucGVuZGluZ2NiID09PSAwKSB7XG4gICAgICBwcmVmaW5pc2goc3RyZWFtLCBzdGF0ZSk7XG4gICAgICBzdGF0ZS5maW5pc2hlZCA9IHRydWU7XG4gICAgICBzdHJlYW0uZW1pdCgnZmluaXNoJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByZWZpbmlzaChzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5lZWQ7XG59XG5cbmZ1bmN0aW9uIGVuZFdyaXRhYmxlKHN0cmVhbSwgc3RhdGUsIGNiKSB7XG4gIHN0YXRlLmVuZGluZyA9IHRydWU7XG4gIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpO1xuICBpZiAoY2IpIHtcbiAgICBpZiAoc3RhdGUuZmluaXNoZWQpXG4gICAgICBwcm9jZXNzTmV4dFRpY2soY2IpO1xuICAgIGVsc2VcbiAgICAgIHN0cmVhbS5vbmNlKCdmaW5pc2gnLCBjYik7XG4gIH1cbiAgc3RhdGUuZW5kZWQgPSB0cnVlO1xufVxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIE5PVEU6IFRoZXNlIHR5cGUgY2hlY2tpbmcgZnVuY3Rpb25zIGludGVudGlvbmFsbHkgZG9uJ3QgdXNlIGBpbnN0YW5jZW9mYFxuLy8gYmVjYXVzZSBpdCBpcyBmcmFnaWxlIGFuZCBjYW4gYmUgZWFzaWx5IGZha2VkIHdpdGggYE9iamVjdC5jcmVhdGUoKWAuXG5cbmZ1bmN0aW9uIGlzQXJyYXkoYXJnKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KSB7XG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXJnKTtcbiAgfVxuICByZXR1cm4gb2JqZWN0VG9TdHJpbmcoYXJnKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn1cbmV4cG9ydHMuaXNBcnJheSA9IGlzQXJyYXk7XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJztcbn1cbmV4cG9ydHMuaXNCb29sZWFuID0gaXNCb29sZWFuO1xuXG5mdW5jdGlvbiBpc051bGwoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbCA9IGlzTnVsbDtcblxuZnVuY3Rpb24gaXNOdWxsT3JVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsT3JVbmRlZmluZWQgPSBpc051bGxPclVuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cbmV4cG9ydHMuaXNOdW1iZXIgPSBpc051bWJlcjtcblxuZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3RyaW5nJztcbn1cbmV4cG9ydHMuaXNTdHJpbmcgPSBpc1N0cmluZztcblxuZnVuY3Rpb24gaXNTeW1ib2woYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3ltYm9sJztcbn1cbmV4cG9ydHMuaXNTeW1ib2wgPSBpc1N5bWJvbDtcblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cbmV4cG9ydHMuaXNVbmRlZmluZWQgPSBpc1VuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNSZWdFeHAocmUpIHtcbiAgcmV0dXJuIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5leHBvcnRzLmlzUmVnRXhwID0gaXNSZWdFeHA7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuZXhwb3J0cy5pc09iamVjdCA9IGlzT2JqZWN0O1xuXG5mdW5jdGlvbiBpc0RhdGUoZCkge1xuICByZXR1cm4gb2JqZWN0VG9TdHJpbmcoZCkgPT09ICdbb2JqZWN0IERhdGVdJztcbn1cbmV4cG9ydHMuaXNEYXRlID0gaXNEYXRlO1xuXG5mdW5jdGlvbiBpc0Vycm9yKGUpIHtcbiAgcmV0dXJuIChvYmplY3RUb1N0cmluZyhlKSA9PT0gJ1tvYmplY3QgRXJyb3JdJyB8fCBlIGluc3RhbmNlb2YgRXJyb3IpO1xufVxuZXhwb3J0cy5pc0Vycm9yID0gaXNFcnJvcjtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5leHBvcnRzLmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uO1xuXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZShhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbCB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnbnVtYmVyJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N0cmluZycgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnIHx8ICAvLyBFUzYgc3ltYm9sXG4gICAgICAgICB0eXBlb2YgYXJnID09PSAndW5kZWZpbmVkJztcbn1cbmV4cG9ydHMuaXNQcmltaXRpdmUgPSBpc1ByaW1pdGl2ZTtcblxuZXhwb3J0cy5pc0J1ZmZlciA9IEJ1ZmZlci5pc0J1ZmZlcjtcblxuZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pZiAoIXByb2Nlc3MudmVyc2lvbiB8fFxuICAgIHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKCd2MC4nKSA9PT0gMCB8fFxuICAgIHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKCd2MS4nKSA9PT0gMCAmJiBwcm9jZXNzLnZlcnNpb24uaW5kZXhPZigndjEuOC4nKSAhPT0gMCkge1xuICBtb2R1bGUuZXhwb3J0cyA9IG5leHRUaWNrO1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBwcm9jZXNzLm5leHRUaWNrO1xufVxuXG5mdW5jdGlvbiBuZXh0VGljayhmbikge1xuICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoIC0gMSk7XG4gIHZhciBpID0gMDtcbiAgd2hpbGUgKGkgPCBhcmdzLmxlbmd0aCkge1xuICAgIGFyZ3NbaSsrXSA9IGFyZ3VtZW50c1tpXTtcbiAgfVxuICBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGljaygpIHtcbiAgICBmbi5hcHBseShudWxsLCBhcmdzKTtcbiAgfSk7XG59XG4iLCJcbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBkZXByZWNhdGU7XG5cbi8qKlxuICogTWFyayB0aGF0IGEgbWV0aG9kIHNob3VsZCBub3QgYmUgdXNlZC5cbiAqIFJldHVybnMgYSBtb2RpZmllZCBmdW5jdGlvbiB3aGljaCB3YXJucyBvbmNlIGJ5IGRlZmF1bHQuXG4gKlxuICogSWYgYGxvY2FsU3RvcmFnZS5ub0RlcHJlY2F0aW9uID0gdHJ1ZWAgaXMgc2V0LCB0aGVuIGl0IGlzIGEgbm8tb3AuXG4gKlxuICogSWYgYGxvY2FsU3RvcmFnZS50aHJvd0RlcHJlY2F0aW9uID0gdHJ1ZWAgaXMgc2V0LCB0aGVuIGRlcHJlY2F0ZWQgZnVuY3Rpb25zXG4gKiB3aWxsIHRocm93IGFuIEVycm9yIHdoZW4gaW52b2tlZC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLnRyYWNlRGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gZGVwcmVjYXRlZCBmdW5jdGlvbnNcbiAqIHdpbGwgaW52b2tlIGBjb25zb2xlLnRyYWNlKClgIGluc3RlYWQgb2YgYGNvbnNvbGUuZXJyb3IoKWAuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gLSB0aGUgZnVuY3Rpb24gdG8gZGVwcmVjYXRlXG4gKiBAcGFyYW0ge1N0cmluZ30gbXNnIC0gdGhlIHN0cmluZyB0byBwcmludCB0byB0aGUgY29uc29sZSB3aGVuIGBmbmAgaXMgaW52b2tlZFxuICogQHJldHVybnMge0Z1bmN0aW9ufSBhIG5ldyBcImRlcHJlY2F0ZWRcIiB2ZXJzaW9uIG9mIGBmbmBcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZGVwcmVjYXRlIChmbiwgbXNnKSB7XG4gIGlmIChjb25maWcoJ25vRGVwcmVjYXRpb24nKSkge1xuICAgIHJldHVybiBmbjtcbiAgfVxuXG4gIHZhciB3YXJuZWQgPSBmYWxzZTtcbiAgZnVuY3Rpb24gZGVwcmVjYXRlZCgpIHtcbiAgICBpZiAoIXdhcm5lZCkge1xuICAgICAgaWYgKGNvbmZpZygndGhyb3dEZXByZWNhdGlvbicpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgICAgfSBlbHNlIGlmIChjb25maWcoJ3RyYWNlRGVwcmVjYXRpb24nKSkge1xuICAgICAgICBjb25zb2xlLnRyYWNlKG1zZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLndhcm4obXNnKTtcbiAgICAgIH1cbiAgICAgIHdhcm5lZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgcmV0dXJuIGRlcHJlY2F0ZWQ7XG59XG5cbi8qKlxuICogQ2hlY2tzIGBsb2NhbFN0b3JhZ2VgIGZvciBib29sZWFuIHZhbHVlcyBmb3IgdGhlIGdpdmVuIGBuYW1lYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICogQHJldHVybnMge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBjb25maWcgKG5hbWUpIHtcbiAgLy8gYWNjZXNzaW5nIGdsb2JhbC5sb2NhbFN0b3JhZ2UgY2FuIHRyaWdnZXIgYSBET01FeGNlcHRpb24gaW4gc2FuZGJveGVkIGlmcmFtZXNcbiAgdHJ5IHtcbiAgICBpZiAoIWdsb2JhbC5sb2NhbFN0b3JhZ2UpIHJldHVybiBmYWxzZTtcbiAgfSBjYXRjaCAoXykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgdmFsID0gZ2xvYmFsLmxvY2FsU3RvcmFnZVtuYW1lXTtcbiAgaWYgKG51bGwgPT0gdmFsKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiBTdHJpbmcodmFsKS50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZSc7XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3Bhc3N0aHJvdWdoLmpzXCIpXG4iLCJ2YXIgU3RyZWFtID0gKGZ1bmN0aW9uICgpe1xuICB0cnkge1xuICAgIHJldHVybiByZXF1aXJlKCdzdCcgKyAncmVhbScpOyAvLyBoYWNrIHRvIGZpeCBhIGNpcmN1bGFyIGRlcGVuZGVuY3kgaXNzdWUgd2hlbiB1c2VkIHdpdGggYnJvd3NlcmlmeVxuICB9IGNhdGNoKF8pe31cbn0oKSk7XG5leHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX3JlYWRhYmxlLmpzJyk7XG5leHBvcnRzLlN0cmVhbSA9IFN0cmVhbSB8fCBleHBvcnRzO1xuZXhwb3J0cy5SZWFkYWJsZSA9IGV4cG9ydHM7XG5leHBvcnRzLldyaXRhYmxlID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV93cml0YWJsZS5qcycpO1xuZXhwb3J0cy5EdXBsZXggPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX2R1cGxleC5qcycpO1xuZXhwb3J0cy5UcmFuc2Zvcm0gPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qcycpO1xuZXhwb3J0cy5QYXNzVGhyb3VnaCA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanMnKTtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzXCIpXG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzXCIpXG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW07XG5cbnZhciBFRSA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlcjtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmluaGVyaXRzKFN0cmVhbSwgRUUpO1xuU3RyZWFtLlJlYWRhYmxlID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLmpzJyk7XG5TdHJlYW0uV3JpdGFibGUgPSByZXF1aXJlKCdyZWFkYWJsZS1zdHJlYW0vd3JpdGFibGUuanMnKTtcblN0cmVhbS5EdXBsZXggPSByZXF1aXJlKCdyZWFkYWJsZS1zdHJlYW0vZHVwbGV4LmpzJyk7XG5TdHJlYW0uVHJhbnNmb3JtID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL3RyYW5zZm9ybS5qcycpO1xuU3RyZWFtLlBhc3NUaHJvdWdoID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL3Bhc3N0aHJvdWdoLmpzJyk7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuNC54XG5TdHJlYW0uU3RyZWFtID0gU3RyZWFtO1xuXG5cblxuLy8gb2xkLXN0eWxlIHN0cmVhbXMuICBOb3RlIHRoYXQgdGhlIHBpcGUgbWV0aG9kICh0aGUgb25seSByZWxldmFudFxuLy8gcGFydCBvZiB0aGlzIGNsYXNzKSBpcyBvdmVycmlkZGVuIGluIHRoZSBSZWFkYWJsZSBjbGFzcy5cblxuZnVuY3Rpb24gU3RyZWFtKCkge1xuICBFRS5jYWxsKHRoaXMpO1xufVxuXG5TdHJlYW0ucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbihkZXN0LCBvcHRpb25zKSB7XG4gIHZhciBzb3VyY2UgPSB0aGlzO1xuXG4gIGZ1bmN0aW9uIG9uZGF0YShjaHVuaykge1xuICAgIGlmIChkZXN0LndyaXRhYmxlKSB7XG4gICAgICBpZiAoZmFsc2UgPT09IGRlc3Qud3JpdGUoY2h1bmspICYmIHNvdXJjZS5wYXVzZSkge1xuICAgICAgICBzb3VyY2UucGF1c2UoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzb3VyY2Uub24oJ2RhdGEnLCBvbmRhdGEpO1xuXG4gIGZ1bmN0aW9uIG9uZHJhaW4oKSB7XG4gICAgaWYgKHNvdXJjZS5yZWFkYWJsZSAmJiBzb3VyY2UucmVzdW1lKSB7XG4gICAgICBzb3VyY2UucmVzdW1lKCk7XG4gICAgfVxuICB9XG5cbiAgZGVzdC5vbignZHJhaW4nLCBvbmRyYWluKTtcblxuICAvLyBJZiB0aGUgJ2VuZCcgb3B0aW9uIGlzIG5vdCBzdXBwbGllZCwgZGVzdC5lbmQoKSB3aWxsIGJlIGNhbGxlZCB3aGVuXG4gIC8vIHNvdXJjZSBnZXRzIHRoZSAnZW5kJyBvciAnY2xvc2UnIGV2ZW50cy4gIE9ubHkgZGVzdC5lbmQoKSBvbmNlLlxuICBpZiAoIWRlc3QuX2lzU3RkaW8gJiYgKCFvcHRpb25zIHx8IG9wdGlvbnMuZW5kICE9PSBmYWxzZSkpIHtcbiAgICBzb3VyY2Uub24oJ2VuZCcsIG9uZW5kKTtcbiAgICBzb3VyY2Uub24oJ2Nsb3NlJywgb25jbG9zZSk7XG4gIH1cblxuICB2YXIgZGlkT25FbmQgPSBmYWxzZTtcbiAgZnVuY3Rpb24gb25lbmQoKSB7XG4gICAgaWYgKGRpZE9uRW5kKSByZXR1cm47XG4gICAgZGlkT25FbmQgPSB0cnVlO1xuXG4gICAgZGVzdC5lbmQoKTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gb25jbG9zZSgpIHtcbiAgICBpZiAoZGlkT25FbmQpIHJldHVybjtcbiAgICBkaWRPbkVuZCA9IHRydWU7XG5cbiAgICBpZiAodHlwZW9mIGRlc3QuZGVzdHJveSA9PT0gJ2Z1bmN0aW9uJykgZGVzdC5kZXN0cm95KCk7XG4gIH1cblxuICAvLyBkb24ndCBsZWF2ZSBkYW5nbGluZyBwaXBlcyB3aGVuIHRoZXJlIGFyZSBlcnJvcnMuXG4gIGZ1bmN0aW9uIG9uZXJyb3IoZXIpIHtcbiAgICBjbGVhbnVwKCk7XG4gICAgaWYgKEVFLmxpc3RlbmVyQ291bnQodGhpcywgJ2Vycm9yJykgPT09IDApIHtcbiAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgc3RyZWFtIGVycm9yIGluIHBpcGUuXG4gICAgfVxuICB9XG5cbiAgc291cmNlLm9uKCdlcnJvcicsIG9uZXJyb3IpO1xuICBkZXN0Lm9uKCdlcnJvcicsIG9uZXJyb3IpO1xuXG4gIC8vIHJlbW92ZSBhbGwgdGhlIGV2ZW50IGxpc3RlbmVycyB0aGF0IHdlcmUgYWRkZWQuXG4gIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgb25kYXRhKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdkcmFpbicsIG9uZHJhaW4pO1xuXG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBvbmVuZCk7XG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuXG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIGNsZWFudXApO1xuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBjbGVhbnVwKTtcblxuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgY2xlYW51cCk7XG4gIH1cblxuICBzb3VyY2Uub24oJ2VuZCcsIGNsZWFudXApO1xuICBzb3VyY2Uub24oJ2Nsb3NlJywgY2xlYW51cCk7XG5cbiAgZGVzdC5vbignY2xvc2UnLCBjbGVhbnVwKTtcblxuICBkZXN0LmVtaXQoJ3BpcGUnLCBzb3VyY2UpO1xuXG4gIC8vIEFsbG93IGZvciB1bml4LWxpa2UgdXNhZ2U6IEEucGlwZShCKS5waXBlKEMpXG4gIHJldHVybiBkZXN0O1xufTtcbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuXG52YXIgaXNCdWZmZXJFbmNvZGluZyA9IEJ1ZmZlci5pc0VuY29kaW5nXG4gIHx8IGZ1bmN0aW9uKGVuY29kaW5nKSB7XG4gICAgICAgc3dpdGNoIChlbmNvZGluZyAmJiBlbmNvZGluZy50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICBjYXNlICdoZXgnOiBjYXNlICd1dGY4JzogY2FzZSAndXRmLTgnOiBjYXNlICdhc2NpaSc6IGNhc2UgJ2JpbmFyeSc6IGNhc2UgJ2Jhc2U2NCc6IGNhc2UgJ3VjczInOiBjYXNlICd1Y3MtMic6IGNhc2UgJ3V0ZjE2bGUnOiBjYXNlICd1dGYtMTZsZSc6IGNhc2UgJ3Jhdyc6IHJldHVybiB0cnVlO1xuICAgICAgICAgZGVmYXVsdDogcmV0dXJuIGZhbHNlO1xuICAgICAgIH1cbiAgICAgfVxuXG5cbmZ1bmN0aW9uIGFzc2VydEVuY29kaW5nKGVuY29kaW5nKSB7XG4gIGlmIChlbmNvZGluZyAmJiAhaXNCdWZmZXJFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZyk7XG4gIH1cbn1cblxuLy8gU3RyaW5nRGVjb2RlciBwcm92aWRlcyBhbiBpbnRlcmZhY2UgZm9yIGVmZmljaWVudGx5IHNwbGl0dGluZyBhIHNlcmllcyBvZlxuLy8gYnVmZmVycyBpbnRvIGEgc2VyaWVzIG9mIEpTIHN0cmluZ3Mgd2l0aG91dCBicmVha2luZyBhcGFydCBtdWx0aS1ieXRlXG4vLyBjaGFyYWN0ZXJzLiBDRVNVLTggaXMgaGFuZGxlZCBhcyBwYXJ0IG9mIHRoZSBVVEYtOCBlbmNvZGluZy5cbi8vXG4vLyBAVE9ETyBIYW5kbGluZyBhbGwgZW5jb2RpbmdzIGluc2lkZSBhIHNpbmdsZSBvYmplY3QgbWFrZXMgaXQgdmVyeSBkaWZmaWN1bHRcbi8vIHRvIHJlYXNvbiBhYm91dCB0aGlzIGNvZGUsIHNvIGl0IHNob3VsZCBiZSBzcGxpdCB1cCBpbiB0aGUgZnV0dXJlLlxuLy8gQFRPRE8gVGhlcmUgc2hvdWxkIGJlIGEgdXRmOC1zdHJpY3QgZW5jb2RpbmcgdGhhdCByZWplY3RzIGludmFsaWQgVVRGLTggY29kZVxuLy8gcG9pbnRzIGFzIHVzZWQgYnkgQ0VTVS04LlxudmFyIFN0cmluZ0RlY29kZXIgPSBleHBvcnRzLlN0cmluZ0RlY29kZXIgPSBmdW5jdGlvbihlbmNvZGluZykge1xuICB0aGlzLmVuY29kaW5nID0gKGVuY29kaW5nIHx8ICd1dGY4JykudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9bLV9dLywgJycpO1xuICBhc3NlcnRFbmNvZGluZyhlbmNvZGluZyk7XG4gIHN3aXRjaCAodGhpcy5lbmNvZGluZykge1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgLy8gQ0VTVS04IHJlcHJlc2VudHMgZWFjaCBvZiBTdXJyb2dhdGUgUGFpciBieSAzLWJ5dGVzXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAzO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICAvLyBVVEYtMTYgcmVwcmVzZW50cyBlYWNoIG9mIFN1cnJvZ2F0ZSBQYWlyIGJ5IDItYnl0ZXNcbiAgICAgIHRoaXMuc3Vycm9nYXRlU2l6ZSA9IDI7XG4gICAgICB0aGlzLmRldGVjdEluY29tcGxldGVDaGFyID0gdXRmMTZEZXRlY3RJbmNvbXBsZXRlQ2hhcjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAvLyBCYXNlLTY0IHN0b3JlcyAzIGJ5dGVzIGluIDQgY2hhcnMsIGFuZCBwYWRzIHRoZSByZW1haW5kZXIuXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAzO1xuICAgICAgdGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IGJhc2U2NERldGVjdEluY29tcGxldGVDaGFyO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRoaXMud3JpdGUgPSBwYXNzVGhyb3VnaFdyaXRlO1xuICAgICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gRW5vdWdoIHNwYWNlIHRvIHN0b3JlIGFsbCBieXRlcyBvZiBhIHNpbmdsZSBjaGFyYWN0ZXIuIFVURi04IG5lZWRzIDRcbiAgLy8gYnl0ZXMsIGJ1dCBDRVNVLTggbWF5IHJlcXVpcmUgdXAgdG8gNiAoMyBieXRlcyBwZXIgc3Vycm9nYXRlKS5cbiAgdGhpcy5jaGFyQnVmZmVyID0gbmV3IEJ1ZmZlcig2KTtcbiAgLy8gTnVtYmVyIG9mIGJ5dGVzIHJlY2VpdmVkIGZvciB0aGUgY3VycmVudCBpbmNvbXBsZXRlIG11bHRpLWJ5dGUgY2hhcmFjdGVyLlxuICB0aGlzLmNoYXJSZWNlaXZlZCA9IDA7XG4gIC8vIE51bWJlciBvZiBieXRlcyBleHBlY3RlZCBmb3IgdGhlIGN1cnJlbnQgaW5jb21wbGV0ZSBtdWx0aS1ieXRlIGNoYXJhY3Rlci5cbiAgdGhpcy5jaGFyTGVuZ3RoID0gMDtcbn07XG5cblxuLy8gd3JpdGUgZGVjb2RlcyB0aGUgZ2l2ZW4gYnVmZmVyIGFuZCByZXR1cm5zIGl0IGFzIEpTIHN0cmluZyB0aGF0IGlzXG4vLyBndWFyYW50ZWVkIHRvIG5vdCBjb250YWluIGFueSBwYXJ0aWFsIG11bHRpLWJ5dGUgY2hhcmFjdGVycy4gQW55IHBhcnRpYWxcbi8vIGNoYXJhY3RlciBmb3VuZCBhdCB0aGUgZW5kIG9mIHRoZSBidWZmZXIgaXMgYnVmZmVyZWQgdXAsIGFuZCB3aWxsIGJlXG4vLyByZXR1cm5lZCB3aGVuIGNhbGxpbmcgd3JpdGUgYWdhaW4gd2l0aCB0aGUgcmVtYWluaW5nIGJ5dGVzLlxuLy9cbi8vIE5vdGU6IENvbnZlcnRpbmcgYSBCdWZmZXIgY29udGFpbmluZyBhbiBvcnBoYW4gc3Vycm9nYXRlIHRvIGEgU3RyaW5nXG4vLyBjdXJyZW50bHkgd29ya3MsIGJ1dCBjb252ZXJ0aW5nIGEgU3RyaW5nIHRvIGEgQnVmZmVyICh2aWEgYG5ldyBCdWZmZXJgLCBvclxuLy8gQnVmZmVyI3dyaXRlKSB3aWxsIHJlcGxhY2UgaW5jb21wbGV0ZSBzdXJyb2dhdGVzIHdpdGggdGhlIHVuaWNvZGVcbi8vIHJlcGxhY2VtZW50IGNoYXJhY3Rlci4gU2VlIGh0dHBzOi8vY29kZXJldmlldy5jaHJvbWl1bS5vcmcvMTIxMTczMDA5LyAuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICB2YXIgY2hhclN0ciA9ICcnO1xuICAvLyBpZiBvdXIgbGFzdCB3cml0ZSBlbmRlZCB3aXRoIGFuIGluY29tcGxldGUgbXVsdGlieXRlIGNoYXJhY3RlclxuICB3aGlsZSAodGhpcy5jaGFyTGVuZ3RoKSB7XG4gICAgLy8gZGV0ZXJtaW5lIGhvdyBtYW55IHJlbWFpbmluZyBieXRlcyB0aGlzIGJ1ZmZlciBoYXMgdG8gb2ZmZXIgZm9yIHRoaXMgY2hhclxuICAgIHZhciBhdmFpbGFibGUgPSAoYnVmZmVyLmxlbmd0aCA+PSB0aGlzLmNoYXJMZW5ndGggLSB0aGlzLmNoYXJSZWNlaXZlZCkgP1xuICAgICAgICB0aGlzLmNoYXJMZW5ndGggLSB0aGlzLmNoYXJSZWNlaXZlZCA6XG4gICAgICAgIGJ1ZmZlci5sZW5ndGg7XG5cbiAgICAvLyBhZGQgdGhlIG5ldyBieXRlcyB0byB0aGUgY2hhciBidWZmZXJcbiAgICBidWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsIHRoaXMuY2hhclJlY2VpdmVkLCAwLCBhdmFpbGFibGUpO1xuICAgIHRoaXMuY2hhclJlY2VpdmVkICs9IGF2YWlsYWJsZTtcblxuICAgIGlmICh0aGlzLmNoYXJSZWNlaXZlZCA8IHRoaXMuY2hhckxlbmd0aCkge1xuICAgICAgLy8gc3RpbGwgbm90IGVub3VnaCBjaGFycyBpbiB0aGlzIGJ1ZmZlcj8gd2FpdCBmb3IgbW9yZSAuLi5cbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICAvLyByZW1vdmUgYnl0ZXMgYmVsb25naW5nIHRvIHRoZSBjdXJyZW50IGNoYXJhY3RlciBmcm9tIHRoZSBidWZmZXJcbiAgICBidWZmZXIgPSBidWZmZXIuc2xpY2UoYXZhaWxhYmxlLCBidWZmZXIubGVuZ3RoKTtcblxuICAgIC8vIGdldCB0aGUgY2hhcmFjdGVyIHRoYXQgd2FzIHNwbGl0XG4gICAgY2hhclN0ciA9IHRoaXMuY2hhckJ1ZmZlci5zbGljZSgwLCB0aGlzLmNoYXJMZW5ndGgpLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpO1xuXG4gICAgLy8gQ0VTVS04OiBsZWFkIHN1cnJvZ2F0ZSAoRDgwMC1EQkZGKSBpcyBhbHNvIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlclxuICAgIHZhciBjaGFyQ29kZSA9IGNoYXJTdHIuY2hhckNvZGVBdChjaGFyU3RyLmxlbmd0aCAtIDEpO1xuICAgIGlmIChjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggKz0gdGhpcy5zdXJyb2dhdGVTaXplO1xuICAgICAgY2hhclN0ciA9ICcnO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHRoaXMuY2hhclJlY2VpdmVkID0gdGhpcy5jaGFyTGVuZ3RoID0gMDtcblxuICAgIC8vIGlmIHRoZXJlIGFyZSBubyBtb3JlIGJ5dGVzIGluIHRoaXMgYnVmZmVyLCBqdXN0IGVtaXQgb3VyIGNoYXJcbiAgICBpZiAoYnVmZmVyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGNoYXJTdHI7XG4gICAgfVxuICAgIGJyZWFrO1xuICB9XG5cbiAgLy8gZGV0ZXJtaW5lIGFuZCBzZXQgY2hhckxlbmd0aCAvIGNoYXJSZWNlaXZlZFxuICB0aGlzLmRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcik7XG5cbiAgdmFyIGVuZCA9IGJ1ZmZlci5sZW5ndGg7XG4gIGlmICh0aGlzLmNoYXJMZW5ndGgpIHtcbiAgICAvLyBidWZmZXIgdGhlIGluY29tcGxldGUgY2hhcmFjdGVyIGJ5dGVzIHdlIGdvdFxuICAgIGJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgMCwgYnVmZmVyLmxlbmd0aCAtIHRoaXMuY2hhclJlY2VpdmVkLCBlbmQpO1xuICAgIGVuZCAtPSB0aGlzLmNoYXJSZWNlaXZlZDtcbiAgfVxuXG4gIGNoYXJTdHIgKz0gYnVmZmVyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcsIDAsIGVuZCk7XG5cbiAgdmFyIGVuZCA9IGNoYXJTdHIubGVuZ3RoIC0gMTtcbiAgdmFyIGNoYXJDb2RlID0gY2hhclN0ci5jaGFyQ29kZUF0KGVuZCk7XG4gIC8vIENFU1UtODogbGVhZCBzdXJyb2dhdGUgKEQ4MDAtREJGRikgaXMgYWxzbyB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXJcbiAgaWYgKGNoYXJDb2RlID49IDB4RDgwMCAmJiBjaGFyQ29kZSA8PSAweERCRkYpIHtcbiAgICB2YXIgc2l6ZSA9IHRoaXMuc3Vycm9nYXRlU2l6ZTtcbiAgICB0aGlzLmNoYXJMZW5ndGggKz0gc2l6ZTtcbiAgICB0aGlzLmNoYXJSZWNlaXZlZCArPSBzaXplO1xuICAgIHRoaXMuY2hhckJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgc2l6ZSwgMCwgc2l6ZSk7XG4gICAgYnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCAwLCAwLCBzaXplKTtcbiAgICByZXR1cm4gY2hhclN0ci5zdWJzdHJpbmcoMCwgZW5kKTtcbiAgfVxuXG4gIC8vIG9yIGp1c3QgZW1pdCB0aGUgY2hhclN0clxuICByZXR1cm4gY2hhclN0cjtcbn07XG5cbi8vIGRldGVjdEluY29tcGxldGVDaGFyIGRldGVybWluZXMgaWYgdGhlcmUgaXMgYW4gaW5jb21wbGV0ZSBVVEYtOCBjaGFyYWN0ZXIgYXRcbi8vIHRoZSBlbmQgb2YgdGhlIGdpdmVuIGJ1ZmZlci4gSWYgc28sIGl0IHNldHMgdGhpcy5jaGFyTGVuZ3RoIHRvIHRoZSBieXRlXG4vLyBsZW5ndGggdGhhdCBjaGFyYWN0ZXIsIGFuZCBzZXRzIHRoaXMuY2hhclJlY2VpdmVkIHRvIHRoZSBudW1iZXIgb2YgYnl0ZXNcbi8vIHRoYXQgYXJlIGF2YWlsYWJsZSBmb3IgdGhpcyBjaGFyYWN0ZXIuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAvLyBkZXRlcm1pbmUgaG93IG1hbnkgYnl0ZXMgd2UgaGF2ZSB0byBjaGVjayBhdCB0aGUgZW5kIG9mIHRoaXMgYnVmZmVyXG4gIHZhciBpID0gKGJ1ZmZlci5sZW5ndGggPj0gMykgPyAzIDogYnVmZmVyLmxlbmd0aDtcblxuICAvLyBGaWd1cmUgb3V0IGlmIG9uZSBvZiB0aGUgbGFzdCBpIGJ5dGVzIG9mIG91ciBidWZmZXIgYW5ub3VuY2VzIGFuXG4gIC8vIGluY29tcGxldGUgY2hhci5cbiAgZm9yICg7IGkgPiAwOyBpLS0pIHtcbiAgICB2YXIgYyA9IGJ1ZmZlcltidWZmZXIubGVuZ3RoIC0gaV07XG5cbiAgICAvLyBTZWUgaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9VVEYtOCNEZXNjcmlwdGlvblxuXG4gICAgLy8gMTEwWFhYWFhcbiAgICBpZiAoaSA9PSAxICYmIGMgPj4gNSA9PSAweDA2KSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSAyO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gMTExMFhYWFhcbiAgICBpZiAoaSA8PSAyICYmIGMgPj4gNCA9PSAweDBFKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSAzO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gMTExMTBYWFhcbiAgICBpZiAoaSA8PSAzICYmIGMgPj4gMyA9PSAweDFFKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSA0O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHRoaXMuY2hhclJlY2VpdmVkID0gaTtcbn07XG5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICB2YXIgcmVzID0gJyc7XG4gIGlmIChidWZmZXIgJiYgYnVmZmVyLmxlbmd0aClcbiAgICByZXMgPSB0aGlzLndyaXRlKGJ1ZmZlcik7XG5cbiAgaWYgKHRoaXMuY2hhclJlY2VpdmVkKSB7XG4gICAgdmFyIGNyID0gdGhpcy5jaGFyUmVjZWl2ZWQ7XG4gICAgdmFyIGJ1ZiA9IHRoaXMuY2hhckJ1ZmZlcjtcbiAgICB2YXIgZW5jID0gdGhpcy5lbmNvZGluZztcbiAgICByZXMgKz0gYnVmLnNsaWNlKDAsIGNyKS50b1N0cmluZyhlbmMpO1xuICB9XG5cbiAgcmV0dXJuIHJlcztcbn07XG5cbmZ1bmN0aW9uIHBhc3NUaHJvdWdoV3JpdGUoYnVmZmVyKSB7XG4gIHJldHVybiBidWZmZXIudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7XG59XG5cbmZ1bmN0aW9uIHV0ZjE2RGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKSB7XG4gIHRoaXMuY2hhclJlY2VpdmVkID0gYnVmZmVyLmxlbmd0aCAlIDI7XG4gIHRoaXMuY2hhckxlbmd0aCA9IHRoaXMuY2hhclJlY2VpdmVkID8gMiA6IDA7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NERldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcikge1xuICB0aGlzLmNoYXJSZWNlaXZlZCA9IGJ1ZmZlci5sZW5ndGggJSAzO1xuICB0aGlzLmNoYXJMZW5ndGggPSB0aGlzLmNoYXJSZWNlaXZlZCA/IDMgOiAwO1xufVxuIiwidmFyIGluZGV4T2YgPSByZXF1aXJlKCdpbmRleG9mJyk7XG5cbnZhciBPYmplY3Rfa2V5cyA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICBpZiAoT2JqZWN0LmtleXMpIHJldHVybiBPYmplY3Qua2V5cyhvYmopXG4gICAgZWxzZSB7XG4gICAgICAgIHZhciByZXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIga2V5IGluIG9iaikgcmVzLnB1c2goa2V5KVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cbn07XG5cbnZhciBmb3JFYWNoID0gZnVuY3Rpb24gKHhzLCBmbikge1xuICAgIGlmICh4cy5mb3JFYWNoKSByZXR1cm4geHMuZm9yRWFjaChmbilcbiAgICBlbHNlIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZm4oeHNbaV0sIGksIHhzKTtcbiAgICB9XG59O1xuXG52YXIgZGVmaW5lUHJvcCA9IChmdW5jdGlvbigpIHtcbiAgICB0cnkge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdfJywge30pO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24ob2JqLCBuYW1lLCB2YWx1ZSkge1xuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwgbmFtZSwge1xuICAgICAgICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWVcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH07XG4gICAgfSBjYXRjaChlKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihvYmosIG5hbWUsIHZhbHVlKSB7XG4gICAgICAgICAgICBvYmpbbmFtZV0gPSB2YWx1ZTtcbiAgICAgICAgfTtcbiAgICB9XG59KCkpO1xuXG52YXIgZ2xvYmFscyA9IFsnQXJyYXknLCAnQm9vbGVhbicsICdEYXRlJywgJ0Vycm9yJywgJ0V2YWxFcnJvcicsICdGdW5jdGlvbicsXG4nSW5maW5pdHknLCAnSlNPTicsICdNYXRoJywgJ05hTicsICdOdW1iZXInLCAnT2JqZWN0JywgJ1JhbmdlRXJyb3InLFxuJ1JlZmVyZW5jZUVycm9yJywgJ1JlZ0V4cCcsICdTdHJpbmcnLCAnU3ludGF4RXJyb3InLCAnVHlwZUVycm9yJywgJ1VSSUVycm9yJyxcbidkZWNvZGVVUkknLCAnZGVjb2RlVVJJQ29tcG9uZW50JywgJ2VuY29kZVVSSScsICdlbmNvZGVVUklDb21wb25lbnQnLCAnZXNjYXBlJyxcbidldmFsJywgJ2lzRmluaXRlJywgJ2lzTmFOJywgJ3BhcnNlRmxvYXQnLCAncGFyc2VJbnQnLCAndW5kZWZpbmVkJywgJ3VuZXNjYXBlJ107XG5cbmZ1bmN0aW9uIENvbnRleHQoKSB7fVxuQ29udGV4dC5wcm90b3R5cGUgPSB7fTtcblxudmFyIFNjcmlwdCA9IGV4cG9ydHMuU2NyaXB0ID0gZnVuY3Rpb24gTm9kZVNjcmlwdCAoY29kZSkge1xuICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTY3JpcHQpKSByZXR1cm4gbmV3IFNjcmlwdChjb2RlKTtcbiAgICB0aGlzLmNvZGUgPSBjb2RlO1xufTtcblxuU2NyaXB0LnByb3RvdHlwZS5ydW5JbkNvbnRleHQgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIGlmICghKGNvbnRleHQgaW5zdGFuY2VvZiBDb250ZXh0KSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwibmVlZHMgYSAnY29udGV4dCcgYXJndW1lbnQuXCIpO1xuICAgIH1cbiAgICBcbiAgICB2YXIgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgaWYgKCFpZnJhbWUuc3R5bGUpIGlmcmFtZS5zdHlsZSA9IHt9O1xuICAgIGlmcmFtZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIFxuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbiAgICBcbiAgICB2YXIgd2luID0gaWZyYW1lLmNvbnRlbnRXaW5kb3c7XG4gICAgdmFyIHdFdmFsID0gd2luLmV2YWwsIHdFeGVjU2NyaXB0ID0gd2luLmV4ZWNTY3JpcHQ7XG5cbiAgICBpZiAoIXdFdmFsICYmIHdFeGVjU2NyaXB0KSB7XG4gICAgICAgIC8vIHdpbi5ldmFsKCkgbWFnaWNhbGx5IGFwcGVhcnMgd2hlbiB0aGlzIGlzIGNhbGxlZCBpbiBJRTpcbiAgICAgICAgd0V4ZWNTY3JpcHQuY2FsbCh3aW4sICdudWxsJyk7XG4gICAgICAgIHdFdmFsID0gd2luLmV2YWw7XG4gICAgfVxuICAgIFxuICAgIGZvckVhY2goT2JqZWN0X2tleXMoY29udGV4dCksIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgd2luW2tleV0gPSBjb250ZXh0W2tleV07XG4gICAgfSk7XG4gICAgZm9yRWFjaChnbG9iYWxzLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIGlmIChjb250ZXh0W2tleV0pIHtcbiAgICAgICAgICAgIHdpbltrZXldID0gY29udGV4dFtrZXldO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgXG4gICAgdmFyIHdpbktleXMgPSBPYmplY3Rfa2V5cyh3aW4pO1xuXG4gICAgdmFyIHJlcyA9IHdFdmFsLmNhbGwod2luLCB0aGlzLmNvZGUpO1xuICAgIFxuICAgIGZvckVhY2goT2JqZWN0X2tleXMod2luKSwgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAvLyBBdm9pZCBjb3B5aW5nIGNpcmN1bGFyIG9iamVjdHMgbGlrZSBgdG9wYCBhbmQgYHdpbmRvd2AgYnkgb25seVxuICAgICAgICAvLyB1cGRhdGluZyBleGlzdGluZyBjb250ZXh0IHByb3BlcnRpZXMgb3IgbmV3IHByb3BlcnRpZXMgaW4gdGhlIGB3aW5gXG4gICAgICAgIC8vIHRoYXQgd2FzIG9ubHkgaW50cm9kdWNlZCBhZnRlciB0aGUgZXZhbC5cbiAgICAgICAgaWYgKGtleSBpbiBjb250ZXh0IHx8IGluZGV4T2Yod2luS2V5cywga2V5KSA9PT0gLTEpIHtcbiAgICAgICAgICAgIGNvbnRleHRba2V5XSA9IHdpbltrZXldO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICBmb3JFYWNoKGdsb2JhbHMsIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgaWYgKCEoa2V5IGluIGNvbnRleHQpKSB7XG4gICAgICAgICAgICBkZWZpbmVQcm9wKGNvbnRleHQsIGtleSwgd2luW2tleV0pO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgXG4gICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChpZnJhbWUpO1xuICAgIFxuICAgIHJldHVybiByZXM7XG59O1xuXG5TY3JpcHQucHJvdG90eXBlLnJ1bkluVGhpc0NvbnRleHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGV2YWwodGhpcy5jb2RlKTsgLy8gbWF5YmUuLi5cbn07XG5cblNjcmlwdC5wcm90b3R5cGUucnVuSW5OZXdDb250ZXh0ID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICB2YXIgY3R4ID0gU2NyaXB0LmNyZWF0ZUNvbnRleHQoY29udGV4dCk7XG4gICAgdmFyIHJlcyA9IHRoaXMucnVuSW5Db250ZXh0KGN0eCk7XG5cbiAgICBmb3JFYWNoKE9iamVjdF9rZXlzKGN0eCksIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgY29udGV4dFtrZXldID0gY3R4W2tleV07XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcmVzO1xufTtcblxuZm9yRWFjaChPYmplY3Rfa2V5cyhTY3JpcHQucHJvdG90eXBlKSwgZnVuY3Rpb24gKG5hbWUpIHtcbiAgICBleHBvcnRzW25hbWVdID0gU2NyaXB0W25hbWVdID0gZnVuY3Rpb24gKGNvZGUpIHtcbiAgICAgICAgdmFyIHMgPSBTY3JpcHQoY29kZSk7XG4gICAgICAgIHJldHVybiBzW25hbWVdLmFwcGx5KHMsIFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSk7XG4gICAgfTtcbn0pO1xuXG5leHBvcnRzLmNyZWF0ZVNjcmlwdCA9IGZ1bmN0aW9uIChjb2RlKSB7XG4gICAgcmV0dXJuIGV4cG9ydHMuU2NyaXB0KGNvZGUpO1xufTtcblxuZXhwb3J0cy5jcmVhdGVDb250ZXh0ID0gU2NyaXB0LmNyZWF0ZUNvbnRleHQgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHZhciBjb3B5ID0gbmV3IENvbnRleHQoKTtcbiAgICBpZih0eXBlb2YgY29udGV4dCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgZm9yRWFjaChPYmplY3Rfa2V5cyhjb250ZXh0KSwgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgY29weVtrZXldID0gY29udGV4dFtrZXldO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGNvcHk7XG59O1xuIiwiXG52YXIgaW5kZXhPZiA9IFtdLmluZGV4T2Y7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oYXJyLCBvYmope1xuICBpZiAoaW5kZXhPZikgcmV0dXJuIGFyci5pbmRleE9mKG9iaik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGFycltpXSA9PT0gb2JqKSByZXR1cm4gaTtcbiAgfVxuICByZXR1cm4gLTE7XG59OyIsIi8qKlxuICogIENvcHlyaWdodCAoYykgMjAxNC0yMDE1LCBGYWNlYm9vaywgSW5jLlxuICogIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS4gQW4gYWRkaXRpb25hbCBncmFudFxuICogIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICovXG5cbihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gIHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyA/IG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpIDpcbiAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKGZhY3RvcnkpIDpcbiAgZ2xvYmFsLkltbXV0YWJsZSA9IGZhY3RvcnkoKTtcbn0odGhpcywgZnVuY3Rpb24gKCkgeyAndXNlIHN0cmljdCc7dmFyIFNMSUNFJDAgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG5cbiAgZnVuY3Rpb24gY3JlYXRlQ2xhc3MoY3Rvciwgc3VwZXJDbGFzcykge1xuICAgIGlmIChzdXBlckNsYXNzKSB7XG4gICAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcy5wcm90b3R5cGUpO1xuICAgIH1cbiAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3I7XG4gIH1cblxuICBmdW5jdGlvbiBJdGVyYWJsZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzSXRlcmFibGUodmFsdWUpID8gdmFsdWUgOiBTZXEodmFsdWUpO1xuICAgIH1cblxuXG4gIGNyZWF0ZUNsYXNzKEtleWVkSXRlcmFibGUsIEl0ZXJhYmxlKTtcbiAgICBmdW5jdGlvbiBLZXllZEl0ZXJhYmxlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNLZXllZCh2YWx1ZSkgPyB2YWx1ZSA6IEtleWVkU2VxKHZhbHVlKTtcbiAgICB9XG5cblxuICBjcmVhdGVDbGFzcyhJbmRleGVkSXRlcmFibGUsIEl0ZXJhYmxlKTtcbiAgICBmdW5jdGlvbiBJbmRleGVkSXRlcmFibGUodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc0luZGV4ZWQodmFsdWUpID8gdmFsdWUgOiBJbmRleGVkU2VxKHZhbHVlKTtcbiAgICB9XG5cblxuICBjcmVhdGVDbGFzcyhTZXRJdGVyYWJsZSwgSXRlcmFibGUpO1xuICAgIGZ1bmN0aW9uIFNldEl0ZXJhYmxlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNJdGVyYWJsZSh2YWx1ZSkgJiYgIWlzQXNzb2NpYXRpdmUodmFsdWUpID8gdmFsdWUgOiBTZXRTZXEodmFsdWUpO1xuICAgIH1cblxuXG5cbiAgZnVuY3Rpb24gaXNJdGVyYWJsZShtYXliZUl0ZXJhYmxlKSB7XG4gICAgcmV0dXJuICEhKG1heWJlSXRlcmFibGUgJiYgbWF5YmVJdGVyYWJsZVtJU19JVEVSQUJMRV9TRU5USU5FTF0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNLZXllZChtYXliZUtleWVkKSB7XG4gICAgcmV0dXJuICEhKG1heWJlS2V5ZWQgJiYgbWF5YmVLZXllZFtJU19LRVlFRF9TRU5USU5FTF0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNJbmRleGVkKG1heWJlSW5kZXhlZCkge1xuICAgIHJldHVybiAhIShtYXliZUluZGV4ZWQgJiYgbWF5YmVJbmRleGVkW0lTX0lOREVYRURfU0VOVElORUxdKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzQXNzb2NpYXRpdmUobWF5YmVBc3NvY2lhdGl2ZSkge1xuICAgIHJldHVybiBpc0tleWVkKG1heWJlQXNzb2NpYXRpdmUpIHx8IGlzSW5kZXhlZChtYXliZUFzc29jaWF0aXZlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzT3JkZXJlZChtYXliZU9yZGVyZWQpIHtcbiAgICByZXR1cm4gISEobWF5YmVPcmRlcmVkICYmIG1heWJlT3JkZXJlZFtJU19PUkRFUkVEX1NFTlRJTkVMXSk7XG4gIH1cblxuICBJdGVyYWJsZS5pc0l0ZXJhYmxlID0gaXNJdGVyYWJsZTtcbiAgSXRlcmFibGUuaXNLZXllZCA9IGlzS2V5ZWQ7XG4gIEl0ZXJhYmxlLmlzSW5kZXhlZCA9IGlzSW5kZXhlZDtcbiAgSXRlcmFibGUuaXNBc3NvY2lhdGl2ZSA9IGlzQXNzb2NpYXRpdmU7XG4gIEl0ZXJhYmxlLmlzT3JkZXJlZCA9IGlzT3JkZXJlZDtcblxuICBJdGVyYWJsZS5LZXllZCA9IEtleWVkSXRlcmFibGU7XG4gIEl0ZXJhYmxlLkluZGV4ZWQgPSBJbmRleGVkSXRlcmFibGU7XG4gIEl0ZXJhYmxlLlNldCA9IFNldEl0ZXJhYmxlO1xuXG5cbiAgdmFyIElTX0lURVJBQkxFX1NFTlRJTkVMID0gJ0BAX19JTU1VVEFCTEVfSVRFUkFCTEVfX0BAJztcbiAgdmFyIElTX0tFWUVEX1NFTlRJTkVMID0gJ0BAX19JTU1VVEFCTEVfS0VZRURfX0BAJztcbiAgdmFyIElTX0lOREVYRURfU0VOVElORUwgPSAnQEBfX0lNTVVUQUJMRV9JTkRFWEVEX19AQCc7XG4gIHZhciBJU19PUkRFUkVEX1NFTlRJTkVMID0gJ0BAX19JTU1VVEFCTEVfT1JERVJFRF9fQEAnO1xuXG4gIC8vIFVzZWQgZm9yIHNldHRpbmcgcHJvdG90eXBlIG1ldGhvZHMgdGhhdCBJRTggY2hva2VzIG9uLlxuICB2YXIgREVMRVRFID0gJ2RlbGV0ZSc7XG5cbiAgLy8gQ29uc3RhbnRzIGRlc2NyaWJpbmcgdGhlIHNpemUgb2YgdHJpZSBub2Rlcy5cbiAgdmFyIFNISUZUID0gNTsgLy8gUmVzdWx0ZWQgaW4gYmVzdCBwZXJmb3JtYW5jZSBhZnRlciBfX19fX18/XG4gIHZhciBTSVpFID0gMSA8PCBTSElGVDtcbiAgdmFyIE1BU0sgPSBTSVpFIC0gMTtcblxuICAvLyBBIGNvbnNpc3RlbnQgc2hhcmVkIHZhbHVlIHJlcHJlc2VudGluZyBcIm5vdCBzZXRcIiB3aGljaCBlcXVhbHMgbm90aGluZyBvdGhlclxuICAvLyB0aGFuIGl0c2VsZiwgYW5kIG5vdGhpbmcgdGhhdCBjb3VsZCBiZSBwcm92aWRlZCBleHRlcm5hbGx5LlxuICB2YXIgTk9UX1NFVCA9IHt9O1xuXG4gIC8vIEJvb2xlYW4gcmVmZXJlbmNlcywgUm91Z2ggZXF1aXZhbGVudCBvZiBgYm9vbCAmYC5cbiAgdmFyIENIQU5HRV9MRU5HVEggPSB7IHZhbHVlOiBmYWxzZSB9O1xuICB2YXIgRElEX0FMVEVSID0geyB2YWx1ZTogZmFsc2UgfTtcblxuICBmdW5jdGlvbiBNYWtlUmVmKHJlZikge1xuICAgIHJlZi52YWx1ZSA9IGZhbHNlO1xuICAgIHJldHVybiByZWY7XG4gIH1cblxuICBmdW5jdGlvbiBTZXRSZWYocmVmKSB7XG4gICAgcmVmICYmIChyZWYudmFsdWUgPSB0cnVlKTtcbiAgfVxuXG4gIC8vIEEgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhIHZhbHVlIHJlcHJlc2VudGluZyBhbiBcIm93bmVyXCIgZm9yIHRyYW5zaWVudCB3cml0ZXNcbiAgLy8gdG8gdHJpZXMuIFRoZSByZXR1cm4gdmFsdWUgd2lsbCBvbmx5IGV2ZXIgZXF1YWwgaXRzZWxmLCBhbmQgd2lsbCBub3QgZXF1YWxcbiAgLy8gdGhlIHJldHVybiBvZiBhbnkgc3Vic2VxdWVudCBjYWxsIG9mIHRoaXMgZnVuY3Rpb24uXG4gIGZ1bmN0aW9uIE93bmVySUQoKSB7fVxuXG4gIC8vIGh0dHA6Ly9qc3BlcmYuY29tL2NvcHktYXJyYXktaW5saW5lXG4gIGZ1bmN0aW9uIGFyckNvcHkoYXJyLCBvZmZzZXQpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfHwgMDtcbiAgICB2YXIgbGVuID0gTWF0aC5tYXgoMCwgYXJyLmxlbmd0aCAtIG9mZnNldCk7XG4gICAgdmFyIG5ld0FyciA9IG5ldyBBcnJheShsZW4pO1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCBsZW47IGlpKyspIHtcbiAgICAgIG5ld0FycltpaV0gPSBhcnJbaWkgKyBvZmZzZXRdO1xuICAgIH1cbiAgICByZXR1cm4gbmV3QXJyO1xuICB9XG5cbiAgZnVuY3Rpb24gZW5zdXJlU2l6ZShpdGVyKSB7XG4gICAgaWYgKGl0ZXIuc2l6ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBpdGVyLnNpemUgPSBpdGVyLl9faXRlcmF0ZShyZXR1cm5UcnVlKTtcbiAgICB9XG4gICAgcmV0dXJuIGl0ZXIuc2l6ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHdyYXBJbmRleChpdGVyLCBpbmRleCkge1xuICAgIC8vIFRoaXMgaW1wbGVtZW50cyBcImlzIGFycmF5IGluZGV4XCIgd2hpY2ggdGhlIEVDTUFTdHJpbmcgc3BlYyBkZWZpbmVzIGFzOlxuICAgIC8vXG4gICAgLy8gICAgIEEgU3RyaW5nIHByb3BlcnR5IG5hbWUgUCBpcyBhbiBhcnJheSBpbmRleCBpZiBhbmQgb25seSBpZlxuICAgIC8vICAgICBUb1N0cmluZyhUb1VpbnQzMihQKSkgaXMgZXF1YWwgdG8gUCBhbmQgVG9VaW50MzIoUCkgaXMgbm90IGVxdWFsXG4gICAgLy8gICAgIHRvIDJeMzLiiJIxLlxuICAgIC8vXG4gICAgLy8gaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWFycmF5LWV4b3RpYy1vYmplY3RzXG4gICAgaWYgKHR5cGVvZiBpbmRleCAhPT0gJ251bWJlcicpIHtcbiAgICAgIHZhciB1aW50MzJJbmRleCA9IGluZGV4ID4+PiAwOyAvLyBOID4+PiAwIGlzIHNob3J0aGFuZCBmb3IgVG9VaW50MzJcbiAgICAgIGlmICgnJyArIHVpbnQzMkluZGV4ICE9PSBpbmRleCB8fCB1aW50MzJJbmRleCA9PT0gNDI5NDk2NzI5NSkge1xuICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgfVxuICAgICAgaW5kZXggPSB1aW50MzJJbmRleDtcbiAgICB9XG4gICAgcmV0dXJuIGluZGV4IDwgMCA/IGVuc3VyZVNpemUoaXRlcikgKyBpbmRleCA6IGluZGV4O1xuICB9XG5cbiAgZnVuY3Rpb24gcmV0dXJuVHJ1ZSgpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHdob2xlU2xpY2UoYmVnaW4sIGVuZCwgc2l6ZSkge1xuICAgIHJldHVybiAoYmVnaW4gPT09IDAgfHwgKHNpemUgIT09IHVuZGVmaW5lZCAmJiBiZWdpbiA8PSAtc2l6ZSkpICYmXG4gICAgICAoZW5kID09PSB1bmRlZmluZWQgfHwgKHNpemUgIT09IHVuZGVmaW5lZCAmJiBlbmQgPj0gc2l6ZSkpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzb2x2ZUJlZ2luKGJlZ2luLCBzaXplKSB7XG4gICAgcmV0dXJuIHJlc29sdmVJbmRleChiZWdpbiwgc2l6ZSwgMCk7XG4gIH1cblxuICBmdW5jdGlvbiByZXNvbHZlRW5kKGVuZCwgc2l6ZSkge1xuICAgIHJldHVybiByZXNvbHZlSW5kZXgoZW5kLCBzaXplLCBzaXplKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc29sdmVJbmRleChpbmRleCwgc2l6ZSwgZGVmYXVsdEluZGV4KSB7XG4gICAgcmV0dXJuIGluZGV4ID09PSB1bmRlZmluZWQgP1xuICAgICAgZGVmYXVsdEluZGV4IDpcbiAgICAgIGluZGV4IDwgMCA/XG4gICAgICAgIE1hdGgubWF4KDAsIHNpemUgKyBpbmRleCkgOlxuICAgICAgICBzaXplID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgIGluZGV4IDpcbiAgICAgICAgICBNYXRoLm1pbihzaXplLCBpbmRleCk7XG4gIH1cblxuICAvKiBnbG9iYWwgU3ltYm9sICovXG5cbiAgdmFyIElURVJBVEVfS0VZUyA9IDA7XG4gIHZhciBJVEVSQVRFX1ZBTFVFUyA9IDE7XG4gIHZhciBJVEVSQVRFX0VOVFJJRVMgPSAyO1xuXG4gIHZhciBSRUFMX0lURVJBVE9SX1NZTUJPTCA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgU3ltYm9sLml0ZXJhdG9yO1xuICB2YXIgRkFVWF9JVEVSQVRPUl9TWU1CT0wgPSAnQEBpdGVyYXRvcic7XG5cbiAgdmFyIElURVJBVE9SX1NZTUJPTCA9IFJFQUxfSVRFUkFUT1JfU1lNQk9MIHx8IEZBVVhfSVRFUkFUT1JfU1lNQk9MO1xuXG5cbiAgZnVuY3Rpb24gSXRlcmF0b3IobmV4dCkge1xuICAgICAgdGhpcy5uZXh0ID0gbmV4dDtcbiAgICB9XG5cbiAgICBJdGVyYXRvci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiAnW0l0ZXJhdG9yXSc7XG4gICAgfTtcblxuXG4gIEl0ZXJhdG9yLktFWVMgPSBJVEVSQVRFX0tFWVM7XG4gIEl0ZXJhdG9yLlZBTFVFUyA9IElURVJBVEVfVkFMVUVTO1xuICBJdGVyYXRvci5FTlRSSUVTID0gSVRFUkFURV9FTlRSSUVTO1xuXG4gIEl0ZXJhdG9yLnByb3RvdHlwZS5pbnNwZWN0ID1cbiAgSXRlcmF0b3IucHJvdG90eXBlLnRvU291cmNlID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy50b1N0cmluZygpOyB9XG4gIEl0ZXJhdG9yLnByb3RvdHlwZVtJVEVSQVRPUl9TWU1CT0xdID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG5cbiAgZnVuY3Rpb24gaXRlcmF0b3JWYWx1ZSh0eXBlLCBrLCB2LCBpdGVyYXRvclJlc3VsdCkge1xuICAgIHZhciB2YWx1ZSA9IHR5cGUgPT09IDAgPyBrIDogdHlwZSA9PT0gMSA/IHYgOiBbaywgdl07XG4gICAgaXRlcmF0b3JSZXN1bHQgPyAoaXRlcmF0b3JSZXN1bHQudmFsdWUgPSB2YWx1ZSkgOiAoaXRlcmF0b3JSZXN1bHQgPSB7XG4gICAgICB2YWx1ZTogdmFsdWUsIGRvbmU6IGZhbHNlXG4gICAgfSk7XG4gICAgcmV0dXJuIGl0ZXJhdG9yUmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gaXRlcmF0b3JEb25lKCkge1xuICAgIHJldHVybiB7IHZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWUgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhc0l0ZXJhdG9yKG1heWJlSXRlcmFibGUpIHtcbiAgICByZXR1cm4gISFnZXRJdGVyYXRvckZuKG1heWJlSXRlcmFibGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNJdGVyYXRvcihtYXliZUl0ZXJhdG9yKSB7XG4gICAgcmV0dXJuIG1heWJlSXRlcmF0b3IgJiYgdHlwZW9mIG1heWJlSXRlcmF0b3IubmV4dCA9PT0gJ2Z1bmN0aW9uJztcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldEl0ZXJhdG9yKGl0ZXJhYmxlKSB7XG4gICAgdmFyIGl0ZXJhdG9yRm4gPSBnZXRJdGVyYXRvckZuKGl0ZXJhYmxlKTtcbiAgICByZXR1cm4gaXRlcmF0b3JGbiAmJiBpdGVyYXRvckZuLmNhbGwoaXRlcmFibGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0SXRlcmF0b3JGbihpdGVyYWJsZSkge1xuICAgIHZhciBpdGVyYXRvckZuID0gaXRlcmFibGUgJiYgKFxuICAgICAgKFJFQUxfSVRFUkFUT1JfU1lNQk9MICYmIGl0ZXJhYmxlW1JFQUxfSVRFUkFUT1JfU1lNQk9MXSkgfHxcbiAgICAgIGl0ZXJhYmxlW0ZBVVhfSVRFUkFUT1JfU1lNQk9MXVxuICAgICk7XG4gICAgaWYgKHR5cGVvZiBpdGVyYXRvckZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gaXRlcmF0b3JGbjtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpc0FycmF5TGlrZSh2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZSAmJiB0eXBlb2YgdmFsdWUubGVuZ3RoID09PSAnbnVtYmVyJztcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKFNlcSwgSXRlcmFibGUpO1xuICAgIGZ1bmN0aW9uIFNlcSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgPyBlbXB0eVNlcXVlbmNlKCkgOlxuICAgICAgICBpc0l0ZXJhYmxlKHZhbHVlKSA/IHZhbHVlLnRvU2VxKCkgOiBzZXFGcm9tVmFsdWUodmFsdWUpO1xuICAgIH1cblxuICAgIFNlcS5vZiA9IGZ1bmN0aW9uKC8qLi4udmFsdWVzKi8pIHtcbiAgICAgIHJldHVybiBTZXEoYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgU2VxLnByb3RvdHlwZS50b1NlcSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIFNlcS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fdG9TdHJpbmcoJ1NlcSB7JywgJ30nKTtcbiAgICB9O1xuXG4gICAgU2VxLnByb3RvdHlwZS5jYWNoZVJlc3VsdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCF0aGlzLl9jYWNoZSAmJiB0aGlzLl9faXRlcmF0ZVVuY2FjaGVkKSB7XG4gICAgICAgIHRoaXMuX2NhY2hlID0gdGhpcy5lbnRyeVNlcSgpLnRvQXJyYXkoKTtcbiAgICAgICAgdGhpcy5zaXplID0gdGhpcy5fY2FjaGUubGVuZ3RoO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIGFic3RyYWN0IF9faXRlcmF0ZVVuY2FjaGVkKGZuLCByZXZlcnNlKVxuXG4gICAgU2VxLnByb3RvdHlwZS5fX2l0ZXJhdGUgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge1xuICAgICAgcmV0dXJuIHNlcUl0ZXJhdGUodGhpcywgZm4sIHJldmVyc2UsIHRydWUpO1xuICAgIH07XG5cbiAgICAvLyBhYnN0cmFjdCBfX2l0ZXJhdG9yVW5jYWNoZWQodHlwZSwgcmV2ZXJzZSlcblxuICAgIFNlcS5wcm90b3R5cGUuX19pdGVyYXRvciA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIHJldHVybiBzZXFJdGVyYXRvcih0aGlzLCB0eXBlLCByZXZlcnNlLCB0cnVlKTtcbiAgICB9O1xuXG5cblxuICBjcmVhdGVDbGFzcyhLZXllZFNlcSwgU2VxKTtcbiAgICBmdW5jdGlvbiBLZXllZFNlcSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgP1xuICAgICAgICBlbXB0eVNlcXVlbmNlKCkudG9LZXllZFNlcSgpIDpcbiAgICAgICAgaXNJdGVyYWJsZSh2YWx1ZSkgP1xuICAgICAgICAgIChpc0tleWVkKHZhbHVlKSA/IHZhbHVlLnRvU2VxKCkgOiB2YWx1ZS5mcm9tRW50cnlTZXEoKSkgOlxuICAgICAgICAgIGtleWVkU2VxRnJvbVZhbHVlKHZhbHVlKTtcbiAgICB9XG5cbiAgICBLZXllZFNlcS5wcm90b3R5cGUudG9LZXllZFNlcSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuXG5cbiAgY3JlYXRlQ2xhc3MoSW5kZXhlZFNlcSwgU2VxKTtcbiAgICBmdW5jdGlvbiBJbmRleGVkU2VxKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCA/IGVtcHR5U2VxdWVuY2UoKSA6XG4gICAgICAgICFpc0l0ZXJhYmxlKHZhbHVlKSA/IGluZGV4ZWRTZXFGcm9tVmFsdWUodmFsdWUpIDpcbiAgICAgICAgaXNLZXllZCh2YWx1ZSkgPyB2YWx1ZS5lbnRyeVNlcSgpIDogdmFsdWUudG9JbmRleGVkU2VxKCk7XG4gICAgfVxuXG4gICAgSW5kZXhlZFNlcS5vZiA9IGZ1bmN0aW9uKC8qLi4udmFsdWVzKi8pIHtcbiAgICAgIHJldHVybiBJbmRleGVkU2VxKGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIEluZGV4ZWRTZXEucHJvdG90eXBlLnRvSW5kZXhlZFNlcSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIEluZGV4ZWRTZXEucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fX3RvU3RyaW5nKCdTZXEgWycsICddJyk7XG4gICAgfTtcblxuICAgIEluZGV4ZWRTZXEucHJvdG90eXBlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7XG4gICAgICByZXR1cm4gc2VxSXRlcmF0ZSh0aGlzLCBmbiwgcmV2ZXJzZSwgZmFsc2UpO1xuICAgIH07XG5cbiAgICBJbmRleGVkU2VxLnByb3RvdHlwZS5fX2l0ZXJhdG9yID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgcmV0dXJuIHNlcUl0ZXJhdG9yKHRoaXMsIHR5cGUsIHJldmVyc2UsIGZhbHNlKTtcbiAgICB9O1xuXG5cblxuICBjcmVhdGVDbGFzcyhTZXRTZXEsIFNlcSk7XG4gICAgZnVuY3Rpb24gU2V0U2VxKHZhbHVlKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gZW1wdHlTZXF1ZW5jZSgpIDpcbiAgICAgICAgIWlzSXRlcmFibGUodmFsdWUpID8gaW5kZXhlZFNlcUZyb21WYWx1ZSh2YWx1ZSkgOlxuICAgICAgICBpc0tleWVkKHZhbHVlKSA/IHZhbHVlLmVudHJ5U2VxKCkgOiB2YWx1ZVxuICAgICAgKS50b1NldFNlcSgpO1xuICAgIH1cblxuICAgIFNldFNlcS5vZiA9IGZ1bmN0aW9uKC8qLi4udmFsdWVzKi8pIHtcbiAgICAgIHJldHVybiBTZXRTZXEoYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgU2V0U2VxLnByb3RvdHlwZS50b1NldFNlcSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuXG5cbiAgU2VxLmlzU2VxID0gaXNTZXE7XG4gIFNlcS5LZXllZCA9IEtleWVkU2VxO1xuICBTZXEuU2V0ID0gU2V0U2VxO1xuICBTZXEuSW5kZXhlZCA9IEluZGV4ZWRTZXE7XG5cbiAgdmFyIElTX1NFUV9TRU5USU5FTCA9ICdAQF9fSU1NVVRBQkxFX1NFUV9fQEAnO1xuXG4gIFNlcS5wcm90b3R5cGVbSVNfU0VRX1NFTlRJTkVMXSA9IHRydWU7XG5cblxuXG4gIGNyZWF0ZUNsYXNzKEFycmF5U2VxLCBJbmRleGVkU2VxKTtcbiAgICBmdW5jdGlvbiBBcnJheVNlcShhcnJheSkge1xuICAgICAgdGhpcy5fYXJyYXkgPSBhcnJheTtcbiAgICAgIHRoaXMuc2l6ZSA9IGFycmF5Lmxlbmd0aDtcbiAgICB9XG5cbiAgICBBcnJheVNlcS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oaW5kZXgsIG5vdFNldFZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5oYXMoaW5kZXgpID8gdGhpcy5fYXJyYXlbd3JhcEluZGV4KHRoaXMsIGluZGV4KV0gOiBub3RTZXRWYWx1ZTtcbiAgICB9O1xuXG4gICAgQXJyYXlTZXEucHJvdG90eXBlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7XG4gICAgICB2YXIgYXJyYXkgPSB0aGlzLl9hcnJheTtcbiAgICAgIHZhciBtYXhJbmRleCA9IGFycmF5Lmxlbmd0aCAtIDE7XG4gICAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDw9IG1heEluZGV4OyBpaSsrKSB7XG4gICAgICAgIGlmIChmbihhcnJheVtyZXZlcnNlID8gbWF4SW5kZXggLSBpaSA6IGlpXSwgaWksIHRoaXMpID09PSBmYWxzZSkge1xuICAgICAgICAgIHJldHVybiBpaSArIDE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBpaTtcbiAgICB9O1xuXG4gICAgQXJyYXlTZXEucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICB2YXIgYXJyYXkgPSB0aGlzLl9hcnJheTtcbiAgICAgIHZhciBtYXhJbmRleCA9IGFycmF5Lmxlbmd0aCAtIDE7XG4gICAgICB2YXIgaWkgPSAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpIFxuICAgICAgICB7cmV0dXJuIGlpID4gbWF4SW5kZXggP1xuICAgICAgICAgIGl0ZXJhdG9yRG9uZSgpIDpcbiAgICAgICAgICBpdGVyYXRvclZhbHVlKHR5cGUsIGlpLCBhcnJheVtyZXZlcnNlID8gbWF4SW5kZXggLSBpaSsrIDogaWkrK10pfVxuICAgICAgKTtcbiAgICB9O1xuXG5cblxuICBjcmVhdGVDbGFzcyhPYmplY3RTZXEsIEtleWVkU2VxKTtcbiAgICBmdW5jdGlvbiBPYmplY3RTZXEob2JqZWN0KSB7XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iamVjdCk7XG4gICAgICB0aGlzLl9vYmplY3QgPSBvYmplY3Q7XG4gICAgICB0aGlzLl9rZXlzID0ga2V5cztcbiAgICAgIHRoaXMuc2l6ZSA9IGtleXMubGVuZ3RoO1xuICAgIH1cblxuICAgIE9iamVjdFNlcS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oa2V5LCBub3RTZXRWYWx1ZSkge1xuICAgICAgaWYgKG5vdFNldFZhbHVlICE9PSB1bmRlZmluZWQgJiYgIXRoaXMuaGFzKGtleSkpIHtcbiAgICAgICAgcmV0dXJuIG5vdFNldFZhbHVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuX29iamVjdFtrZXldO1xuICAgIH07XG5cbiAgICBPYmplY3RTZXEucHJvdG90eXBlLmhhcyA9IGZ1bmN0aW9uKGtleSkge1xuICAgICAgcmV0dXJuIHRoaXMuX29iamVjdC5oYXNPd25Qcm9wZXJ0eShrZXkpO1xuICAgIH07XG5cbiAgICBPYmplY3RTZXEucHJvdG90eXBlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7XG4gICAgICB2YXIgb2JqZWN0ID0gdGhpcy5fb2JqZWN0O1xuICAgICAgdmFyIGtleXMgPSB0aGlzLl9rZXlzO1xuICAgICAgdmFyIG1heEluZGV4ID0ga2V5cy5sZW5ndGggLSAxO1xuICAgICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8PSBtYXhJbmRleDsgaWkrKykge1xuICAgICAgICB2YXIga2V5ID0ga2V5c1tyZXZlcnNlID8gbWF4SW5kZXggLSBpaSA6IGlpXTtcbiAgICAgICAgaWYgKGZuKG9iamVjdFtrZXldLCBrZXksIHRoaXMpID09PSBmYWxzZSkge1xuICAgICAgICAgIHJldHVybiBpaSArIDE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBpaTtcbiAgICB9O1xuXG4gICAgT2JqZWN0U2VxLnByb3RvdHlwZS5fX2l0ZXJhdG9yID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgdmFyIG9iamVjdCA9IHRoaXMuX29iamVjdDtcbiAgICAgIHZhciBrZXlzID0gdGhpcy5fa2V5cztcbiAgICAgIHZhciBtYXhJbmRleCA9IGtleXMubGVuZ3RoIC0gMTtcbiAgICAgIHZhciBpaSA9IDA7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXNbcmV2ZXJzZSA/IG1heEluZGV4IC0gaWkgOiBpaV07XG4gICAgICAgIHJldHVybiBpaSsrID4gbWF4SW5kZXggP1xuICAgICAgICAgIGl0ZXJhdG9yRG9uZSgpIDpcbiAgICAgICAgICBpdGVyYXRvclZhbHVlKHR5cGUsIGtleSwgb2JqZWN0W2tleV0pO1xuICAgICAgfSk7XG4gICAgfTtcblxuICBPYmplY3RTZXEucHJvdG90eXBlW0lTX09SREVSRURfU0VOVElORUxdID0gdHJ1ZTtcblxuXG4gIGNyZWF0ZUNsYXNzKEl0ZXJhYmxlU2VxLCBJbmRleGVkU2VxKTtcbiAgICBmdW5jdGlvbiBJdGVyYWJsZVNlcShpdGVyYWJsZSkge1xuICAgICAgdGhpcy5faXRlcmFibGUgPSBpdGVyYWJsZTtcbiAgICAgIHRoaXMuc2l6ZSA9IGl0ZXJhYmxlLmxlbmd0aCB8fCBpdGVyYWJsZS5zaXplO1xuICAgIH1cblxuICAgIEl0ZXJhYmxlU2VxLnByb3RvdHlwZS5fX2l0ZXJhdGVVbmNhY2hlZCA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7XG4gICAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZVJlc3VsdCgpLl9faXRlcmF0ZShmbiwgcmV2ZXJzZSk7XG4gICAgICB9XG4gICAgICB2YXIgaXRlcmFibGUgPSB0aGlzLl9pdGVyYWJsZTtcbiAgICAgIHZhciBpdGVyYXRvciA9IGdldEl0ZXJhdG9yKGl0ZXJhYmxlKTtcbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIGlmIChpc0l0ZXJhdG9yKGl0ZXJhdG9yKSkge1xuICAgICAgICB2YXIgc3RlcDtcbiAgICAgICAgd2hpbGUgKCEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZSkge1xuICAgICAgICAgIGlmIChmbihzdGVwLnZhbHVlLCBpdGVyYXRpb25zKyssIHRoaXMpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gaXRlcmF0aW9ucztcbiAgICB9O1xuXG4gICAgSXRlcmFibGVTZXEucHJvdG90eXBlLl9faXRlcmF0b3JVbmNhY2hlZCA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlUmVzdWx0KCkuX19pdGVyYXRvcih0eXBlLCByZXZlcnNlKTtcbiAgICAgIH1cbiAgICAgIHZhciBpdGVyYWJsZSA9IHRoaXMuX2l0ZXJhYmxlO1xuICAgICAgdmFyIGl0ZXJhdG9yID0gZ2V0SXRlcmF0b3IoaXRlcmFibGUpO1xuICAgICAgaWYgKCFpc0l0ZXJhdG9yKGl0ZXJhdG9yKSkge1xuICAgICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGl0ZXJhdG9yRG9uZSk7XG4gICAgICB9XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgdmFyIHN0ZXAgPSBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgIHJldHVybiBzdGVwLmRvbmUgPyBzdGVwIDogaXRlcmF0b3JWYWx1ZSh0eXBlLCBpdGVyYXRpb25zKyssIHN0ZXAudmFsdWUpO1xuICAgICAgfSk7XG4gICAgfTtcblxuXG5cbiAgY3JlYXRlQ2xhc3MoSXRlcmF0b3JTZXEsIEluZGV4ZWRTZXEpO1xuICAgIGZ1bmN0aW9uIEl0ZXJhdG9yU2VxKGl0ZXJhdG9yKSB7XG4gICAgICB0aGlzLl9pdGVyYXRvciA9IGl0ZXJhdG9yO1xuICAgICAgdGhpcy5faXRlcmF0b3JDYWNoZSA9IFtdO1xuICAgIH1cblxuICAgIEl0ZXJhdG9yU2VxLnByb3RvdHlwZS5fX2l0ZXJhdGVVbmNhY2hlZCA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7XG4gICAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZVJlc3VsdCgpLl9faXRlcmF0ZShmbiwgcmV2ZXJzZSk7XG4gICAgICB9XG4gICAgICB2YXIgaXRlcmF0b3IgPSB0aGlzLl9pdGVyYXRvcjtcbiAgICAgIHZhciBjYWNoZSA9IHRoaXMuX2l0ZXJhdG9yQ2FjaGU7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICB3aGlsZSAoaXRlcmF0aW9ucyA8IGNhY2hlLmxlbmd0aCkge1xuICAgICAgICBpZiAoZm4oY2FjaGVbaXRlcmF0aW9uc10sIGl0ZXJhdGlvbnMrKywgdGhpcykgPT09IGZhbHNlKSB7XG4gICAgICAgICAgcmV0dXJuIGl0ZXJhdGlvbnM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHZhciBzdGVwO1xuICAgICAgd2hpbGUgKCEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZSkge1xuICAgICAgICB2YXIgdmFsID0gc3RlcC52YWx1ZTtcbiAgICAgICAgY2FjaGVbaXRlcmF0aW9uc10gPSB2YWw7XG4gICAgICAgIGlmIChmbih2YWwsIGl0ZXJhdGlvbnMrKywgdGhpcykgPT09IGZhbHNlKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBpdGVyYXRpb25zO1xuICAgIH07XG5cbiAgICBJdGVyYXRvclNlcS5wcm90b3R5cGUuX19pdGVyYXRvclVuY2FjaGVkID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgaWYgKHJldmVyc2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FjaGVSZXN1bHQoKS5fX2l0ZXJhdG9yKHR5cGUsIHJldmVyc2UpO1xuICAgICAgfVxuICAgICAgdmFyIGl0ZXJhdG9yID0gdGhpcy5faXRlcmF0b3I7XG4gICAgICB2YXIgY2FjaGUgPSB0aGlzLl9pdGVyYXRvckNhY2hlO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIGlmIChpdGVyYXRpb25zID49IGNhY2hlLmxlbmd0aCkge1xuICAgICAgICAgIHZhciBzdGVwID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICAgIGlmIChzdGVwLmRvbmUpIHtcbiAgICAgICAgICAgIHJldHVybiBzdGVwO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYWNoZVtpdGVyYXRpb25zXSA9IHN0ZXAudmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yVmFsdWUodHlwZSwgaXRlcmF0aW9ucywgY2FjaGVbaXRlcmF0aW9ucysrXSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG5cblxuXG4gIC8vICMgcHJhZ21hIEhlbHBlciBmdW5jdGlvbnNcblxuICBmdW5jdGlvbiBpc1NlcShtYXliZVNlcSkge1xuICAgIHJldHVybiAhIShtYXliZVNlcSAmJiBtYXliZVNlcVtJU19TRVFfU0VOVElORUxdKTtcbiAgfVxuXG4gIHZhciBFTVBUWV9TRVE7XG5cbiAgZnVuY3Rpb24gZW1wdHlTZXF1ZW5jZSgpIHtcbiAgICByZXR1cm4gRU1QVFlfU0VRIHx8IChFTVBUWV9TRVEgPSBuZXcgQXJyYXlTZXEoW10pKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGtleWVkU2VxRnJvbVZhbHVlKHZhbHVlKSB7XG4gICAgdmFyIHNlcSA9XG4gICAgICBBcnJheS5pc0FycmF5KHZhbHVlKSA/IG5ldyBBcnJheVNlcSh2YWx1ZSkuZnJvbUVudHJ5U2VxKCkgOlxuICAgICAgaXNJdGVyYXRvcih2YWx1ZSkgPyBuZXcgSXRlcmF0b3JTZXEodmFsdWUpLmZyb21FbnRyeVNlcSgpIDpcbiAgICAgIGhhc0l0ZXJhdG9yKHZhbHVlKSA/IG5ldyBJdGVyYWJsZVNlcSh2YWx1ZSkuZnJvbUVudHJ5U2VxKCkgOlxuICAgICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyA/IG5ldyBPYmplY3RTZXEodmFsdWUpIDpcbiAgICAgIHVuZGVmaW5lZDtcbiAgICBpZiAoIXNlcSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgJ0V4cGVjdGVkIEFycmF5IG9yIGl0ZXJhYmxlIG9iamVjdCBvZiBbaywgdl0gZW50cmllcywgJytcbiAgICAgICAgJ29yIGtleWVkIG9iamVjdDogJyArIHZhbHVlXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gc2VxO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5kZXhlZFNlcUZyb21WYWx1ZSh2YWx1ZSkge1xuICAgIHZhciBzZXEgPSBtYXliZUluZGV4ZWRTZXFGcm9tVmFsdWUodmFsdWUpO1xuICAgIGlmICghc2VxKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAnRXhwZWN0ZWQgQXJyYXkgb3IgaXRlcmFibGUgb2JqZWN0IG9mIHZhbHVlczogJyArIHZhbHVlXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gc2VxO1xuICB9XG5cbiAgZnVuY3Rpb24gc2VxRnJvbVZhbHVlKHZhbHVlKSB7XG4gICAgdmFyIHNlcSA9IG1heWJlSW5kZXhlZFNlcUZyb21WYWx1ZSh2YWx1ZSkgfHxcbiAgICAgICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIG5ldyBPYmplY3RTZXEodmFsdWUpKTtcbiAgICBpZiAoIXNlcSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgJ0V4cGVjdGVkIEFycmF5IG9yIGl0ZXJhYmxlIG9iamVjdCBvZiB2YWx1ZXMsIG9yIGtleWVkIG9iamVjdDogJyArIHZhbHVlXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gc2VxO1xuICB9XG5cbiAgZnVuY3Rpb24gbWF5YmVJbmRleGVkU2VxRnJvbVZhbHVlKHZhbHVlKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIGlzQXJyYXlMaWtlKHZhbHVlKSA/IG5ldyBBcnJheVNlcSh2YWx1ZSkgOlxuICAgICAgaXNJdGVyYXRvcih2YWx1ZSkgPyBuZXcgSXRlcmF0b3JTZXEodmFsdWUpIDpcbiAgICAgIGhhc0l0ZXJhdG9yKHZhbHVlKSA/IG5ldyBJdGVyYWJsZVNlcSh2YWx1ZSkgOlxuICAgICAgdW5kZWZpbmVkXG4gICAgKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNlcUl0ZXJhdGUoc2VxLCBmbiwgcmV2ZXJzZSwgdXNlS2V5cykge1xuICAgIHZhciBjYWNoZSA9IHNlcS5fY2FjaGU7XG4gICAgaWYgKGNhY2hlKSB7XG4gICAgICB2YXIgbWF4SW5kZXggPSBjYWNoZS5sZW5ndGggLSAxO1xuICAgICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8PSBtYXhJbmRleDsgaWkrKykge1xuICAgICAgICB2YXIgZW50cnkgPSBjYWNoZVtyZXZlcnNlID8gbWF4SW5kZXggLSBpaSA6IGlpXTtcbiAgICAgICAgaWYgKGZuKGVudHJ5WzFdLCB1c2VLZXlzID8gZW50cnlbMF0gOiBpaSwgc2VxKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICByZXR1cm4gaWkgKyAxO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gaWk7XG4gICAgfVxuICAgIHJldHVybiBzZXEuX19pdGVyYXRlVW5jYWNoZWQoZm4sIHJldmVyc2UpO1xuICB9XG5cbiAgZnVuY3Rpb24gc2VxSXRlcmF0b3Ioc2VxLCB0eXBlLCByZXZlcnNlLCB1c2VLZXlzKSB7XG4gICAgdmFyIGNhY2hlID0gc2VxLl9jYWNoZTtcbiAgICBpZiAoY2FjaGUpIHtcbiAgICAgIHZhciBtYXhJbmRleCA9IGNhY2hlLmxlbmd0aCAtIDE7XG4gICAgICB2YXIgaWkgPSAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHZhciBlbnRyeSA9IGNhY2hlW3JldmVyc2UgPyBtYXhJbmRleCAtIGlpIDogaWldO1xuICAgICAgICByZXR1cm4gaWkrKyA+IG1heEluZGV4ID9cbiAgICAgICAgICBpdGVyYXRvckRvbmUoKSA6XG4gICAgICAgICAgaXRlcmF0b3JWYWx1ZSh0eXBlLCB1c2VLZXlzID8gZW50cnlbMF0gOiBpaSAtIDEsIGVudHJ5WzFdKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gc2VxLl9faXRlcmF0b3JVbmNhY2hlZCh0eXBlLCByZXZlcnNlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZyb21KUyhqc29uLCBjb252ZXJ0ZXIpIHtcbiAgICByZXR1cm4gY29udmVydGVyID9cbiAgICAgIGZyb21KU1dpdGgoY29udmVydGVyLCBqc29uLCAnJywgeycnOiBqc29ufSkgOlxuICAgICAgZnJvbUpTRGVmYXVsdChqc29uKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZyb21KU1dpdGgoY29udmVydGVyLCBqc29uLCBrZXksIHBhcmVudEpTT04pIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShqc29uKSkge1xuICAgICAgcmV0dXJuIGNvbnZlcnRlci5jYWxsKHBhcmVudEpTT04sIGtleSwgSW5kZXhlZFNlcShqc29uKS5tYXAoZnVuY3Rpb24odiwgaykgIHtyZXR1cm4gZnJvbUpTV2l0aChjb252ZXJ0ZXIsIHYsIGssIGpzb24pfSkpO1xuICAgIH1cbiAgICBpZiAoaXNQbGFpbk9iaihqc29uKSkge1xuICAgICAgcmV0dXJuIGNvbnZlcnRlci5jYWxsKHBhcmVudEpTT04sIGtleSwgS2V5ZWRTZXEoanNvbikubWFwKGZ1bmN0aW9uKHYsIGspICB7cmV0dXJuIGZyb21KU1dpdGgoY29udmVydGVyLCB2LCBrLCBqc29uKX0pKTtcbiAgICB9XG4gICAgcmV0dXJuIGpzb247XG4gIH1cblxuICBmdW5jdGlvbiBmcm9tSlNEZWZhdWx0KGpzb24pIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShqc29uKSkge1xuICAgICAgcmV0dXJuIEluZGV4ZWRTZXEoanNvbikubWFwKGZyb21KU0RlZmF1bHQpLnRvTGlzdCgpO1xuICAgIH1cbiAgICBpZiAoaXNQbGFpbk9iaihqc29uKSkge1xuICAgICAgcmV0dXJuIEtleWVkU2VxKGpzb24pLm1hcChmcm9tSlNEZWZhdWx0KS50b01hcCgpO1xuICAgIH1cbiAgICByZXR1cm4ganNvbjtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzUGxhaW5PYmoodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgJiYgKHZhbHVlLmNvbnN0cnVjdG9yID09PSBPYmplY3QgfHwgdmFsdWUuY29uc3RydWN0b3IgPT09IHVuZGVmaW5lZCk7XG4gIH1cblxuICAvKipcbiAgICogQW4gZXh0ZW5zaW9uIG9mIHRoZSBcInNhbWUtdmFsdWVcIiBhbGdvcml0aG0gYXMgW2Rlc2NyaWJlZCBmb3IgdXNlIGJ5IEVTNiBNYXBcbiAgICogYW5kIFNldF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvTWFwI0tleV9lcXVhbGl0eSlcbiAgICpcbiAgICogTmFOIGlzIGNvbnNpZGVyZWQgdGhlIHNhbWUgYXMgTmFOLCBob3dldmVyIC0wIGFuZCAwIGFyZSBjb25zaWRlcmVkIHRoZSBzYW1lXG4gICAqIHZhbHVlLCB3aGljaCBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgYWxnb3JpdGhtIGRlc2NyaWJlZCBieVxuICAgKiBbYE9iamVjdC5pc2BdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL09iamVjdC9pcykuXG4gICAqXG4gICAqIFRoaXMgaXMgZXh0ZW5kZWQgZnVydGhlciB0byBhbGxvdyBPYmplY3RzIHRvIGRlc2NyaWJlIHRoZSB2YWx1ZXMgdGhleVxuICAgKiByZXByZXNlbnQsIGJ5IHdheSBvZiBgdmFsdWVPZmAgb3IgYGVxdWFsc2AgKGFuZCBgaGFzaENvZGVgKS5cbiAgICpcbiAgICogTm90ZTogYmVjYXVzZSBvZiB0aGlzIGV4dGVuc2lvbiwgdGhlIGtleSBlcXVhbGl0eSBvZiBJbW11dGFibGUuTWFwIGFuZCB0aGVcbiAgICogdmFsdWUgZXF1YWxpdHkgb2YgSW1tdXRhYmxlLlNldCB3aWxsIGRpZmZlciBmcm9tIEVTNiBNYXAgYW5kIFNldC5cbiAgICpcbiAgICogIyMjIERlZmluaW5nIGN1c3RvbSB2YWx1ZXNcbiAgICpcbiAgICogVGhlIGVhc2llc3Qgd2F5IHRvIGRlc2NyaWJlIHRoZSB2YWx1ZSBhbiBvYmplY3QgcmVwcmVzZW50cyBpcyBieSBpbXBsZW1lbnRpbmdcbiAgICogYHZhbHVlT2ZgLiBGb3IgZXhhbXBsZSwgYERhdGVgIHJlcHJlc2VudHMgYSB2YWx1ZSBieSByZXR1cm5pbmcgYSB1bml4XG4gICAqIHRpbWVzdGFtcCBmb3IgYHZhbHVlT2ZgOlxuICAgKlxuICAgKiAgICAgdmFyIGRhdGUxID0gbmV3IERhdGUoMTIzNDU2Nzg5MDAwMCk7IC8vIEZyaSBGZWIgMTMgMjAwOSAuLi5cbiAgICogICAgIHZhciBkYXRlMiA9IG5ldyBEYXRlKDEyMzQ1Njc4OTAwMDApO1xuICAgKiAgICAgZGF0ZTEudmFsdWVPZigpOyAvLyAxMjM0NTY3ODkwMDAwXG4gICAqICAgICBhc3NlcnQoIGRhdGUxICE9PSBkYXRlMiApO1xuICAgKiAgICAgYXNzZXJ0KCBJbW11dGFibGUuaXMoIGRhdGUxLCBkYXRlMiApICk7XG4gICAqXG4gICAqIE5vdGU6IG92ZXJyaWRpbmcgYHZhbHVlT2ZgIG1heSBoYXZlIG90aGVyIGltcGxpY2F0aW9ucyBpZiB5b3UgdXNlIHRoaXMgb2JqZWN0XG4gICAqIHdoZXJlIEphdmFTY3JpcHQgZXhwZWN0cyBhIHByaW1pdGl2ZSwgc3VjaCBhcyBpbXBsaWNpdCBzdHJpbmcgY29lcmNpb24uXG4gICAqXG4gICAqIEZvciBtb3JlIGNvbXBsZXggdHlwZXMsIGVzcGVjaWFsbHkgY29sbGVjdGlvbnMsIGltcGxlbWVudGluZyBgdmFsdWVPZmAgbWF5XG4gICAqIG5vdCBiZSBwZXJmb3JtYW50LiBBbiBhbHRlcm5hdGl2ZSBpcyB0byBpbXBsZW1lbnQgYGVxdWFsc2AgYW5kIGBoYXNoQ29kZWAuXG4gICAqXG4gICAqIGBlcXVhbHNgIHRha2VzIGFub3RoZXIgb2JqZWN0LCBwcmVzdW1hYmx5IG9mIHNpbWlsYXIgdHlwZSwgYW5kIHJldHVybnMgdHJ1ZVxuICAgKiBpZiB0aGUgaXQgaXMgZXF1YWwuIEVxdWFsaXR5IGlzIHN5bW1ldHJpY2FsLCBzbyB0aGUgc2FtZSByZXN1bHQgc2hvdWxkIGJlXG4gICAqIHJldHVybmVkIGlmIHRoaXMgYW5kIHRoZSBhcmd1bWVudCBhcmUgZmxpcHBlZC5cbiAgICpcbiAgICogICAgIGFzc2VydCggYS5lcXVhbHMoYikgPT09IGIuZXF1YWxzKGEpICk7XG4gICAqXG4gICAqIGBoYXNoQ29kZWAgcmV0dXJucyBhIDMyYml0IGludGVnZXIgbnVtYmVyIHJlcHJlc2VudGluZyB0aGUgb2JqZWN0IHdoaWNoIHdpbGxcbiAgICogYmUgdXNlZCB0byBkZXRlcm1pbmUgaG93IHRvIHN0b3JlIHRoZSB2YWx1ZSBvYmplY3QgaW4gYSBNYXAgb3IgU2V0LiBZb3UgbXVzdFxuICAgKiBwcm92aWRlIGJvdGggb3IgbmVpdGhlciBtZXRob2RzLCBvbmUgbXVzdCBub3QgZXhpc3Qgd2l0aG91dCB0aGUgb3RoZXIuXG4gICAqXG4gICAqIEFsc28sIGFuIGltcG9ydGFudCByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGVzZSBtZXRob2RzIG11c3QgYmUgdXBoZWxkOiBpZiB0d29cbiAgICogdmFsdWVzIGFyZSBlcXVhbCwgdGhleSAqbXVzdCogcmV0dXJuIHRoZSBzYW1lIGhhc2hDb2RlLiBJZiB0aGUgdmFsdWVzIGFyZSBub3RcbiAgICogZXF1YWwsIHRoZXkgbWlnaHQgaGF2ZSB0aGUgc2FtZSBoYXNoQ29kZTsgdGhpcyBpcyBjYWxsZWQgYSBoYXNoIGNvbGxpc2lvbixcbiAgICogYW5kIHdoaWxlIHVuZGVzaXJhYmxlIGZvciBwZXJmb3JtYW5jZSByZWFzb25zLCBpdCBpcyBhY2NlcHRhYmxlLlxuICAgKlxuICAgKiAgICAgaWYgKGEuZXF1YWxzKGIpKSB7XG4gICAqICAgICAgIGFzc2VydCggYS5oYXNoQ29kZSgpID09PSBiLmhhc2hDb2RlKCkgKTtcbiAgICogICAgIH1cbiAgICpcbiAgICogQWxsIEltbXV0YWJsZSBjb2xsZWN0aW9ucyBpbXBsZW1lbnQgYGVxdWFsc2AgYW5kIGBoYXNoQ29kZWAuXG4gICAqXG4gICAqL1xuICBmdW5jdGlvbiBpcyh2YWx1ZUEsIHZhbHVlQikge1xuICAgIGlmICh2YWx1ZUEgPT09IHZhbHVlQiB8fCAodmFsdWVBICE9PSB2YWx1ZUEgJiYgdmFsdWVCICE9PSB2YWx1ZUIpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKCF2YWx1ZUEgfHwgIXZhbHVlQikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHZhbHVlQS52YWx1ZU9mID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgIHR5cGVvZiB2YWx1ZUIudmFsdWVPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFsdWVBID0gdmFsdWVBLnZhbHVlT2YoKTtcbiAgICAgIHZhbHVlQiA9IHZhbHVlQi52YWx1ZU9mKCk7XG4gICAgICBpZiAodmFsdWVBID09PSB2YWx1ZUIgfHwgKHZhbHVlQSAhPT0gdmFsdWVBICYmIHZhbHVlQiAhPT0gdmFsdWVCKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmICghdmFsdWVBIHx8ICF2YWx1ZUIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodHlwZW9mIHZhbHVlQS5lcXVhbHMgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgICAgdHlwZW9mIHZhbHVlQi5lcXVhbHMgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgICAgdmFsdWVBLmVxdWFscyh2YWx1ZUIpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZnVuY3Rpb24gZGVlcEVxdWFsKGEsIGIpIHtcbiAgICBpZiAoYSA9PT0gYikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgIWlzSXRlcmFibGUoYikgfHxcbiAgICAgIGEuc2l6ZSAhPT0gdW5kZWZpbmVkICYmIGIuc2l6ZSAhPT0gdW5kZWZpbmVkICYmIGEuc2l6ZSAhPT0gYi5zaXplIHx8XG4gICAgICBhLl9faGFzaCAhPT0gdW5kZWZpbmVkICYmIGIuX19oYXNoICE9PSB1bmRlZmluZWQgJiYgYS5fX2hhc2ggIT09IGIuX19oYXNoIHx8XG4gICAgICBpc0tleWVkKGEpICE9PSBpc0tleWVkKGIpIHx8XG4gICAgICBpc0luZGV4ZWQoYSkgIT09IGlzSW5kZXhlZChiKSB8fFxuICAgICAgaXNPcmRlcmVkKGEpICE9PSBpc09yZGVyZWQoYilcbiAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoYS5zaXplID09PSAwICYmIGIuc2l6ZSA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgdmFyIG5vdEFzc29jaWF0aXZlID0gIWlzQXNzb2NpYXRpdmUoYSk7XG5cbiAgICBpZiAoaXNPcmRlcmVkKGEpKSB7XG4gICAgICB2YXIgZW50cmllcyA9IGEuZW50cmllcygpO1xuICAgICAgcmV0dXJuIGIuZXZlcnkoZnVuY3Rpb24odiwgaykgIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gZW50cmllcy5uZXh0KCkudmFsdWU7XG4gICAgICAgIHJldHVybiBlbnRyeSAmJiBpcyhlbnRyeVsxXSwgdikgJiYgKG5vdEFzc29jaWF0aXZlIHx8IGlzKGVudHJ5WzBdLCBrKSk7XG4gICAgICB9KSAmJiBlbnRyaWVzLm5leHQoKS5kb25lO1xuICAgIH1cblxuICAgIHZhciBmbGlwcGVkID0gZmFsc2U7XG5cbiAgICBpZiAoYS5zaXplID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChiLnNpemUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIGEuY2FjaGVSZXN1bHQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBhLmNhY2hlUmVzdWx0KCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZsaXBwZWQgPSB0cnVlO1xuICAgICAgICB2YXIgXyA9IGE7XG4gICAgICAgIGEgPSBiO1xuICAgICAgICBiID0gXztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgYWxsRXF1YWwgPSB0cnVlO1xuICAgIHZhciBiU2l6ZSA9IGIuX19pdGVyYXRlKGZ1bmN0aW9uKHYsIGspICB7XG4gICAgICBpZiAobm90QXNzb2NpYXRpdmUgPyAhYS5oYXModikgOlxuICAgICAgICAgIGZsaXBwZWQgPyAhaXModiwgYS5nZXQoaywgTk9UX1NFVCkpIDogIWlzKGEuZ2V0KGssIE5PVF9TRVQpLCB2KSkge1xuICAgICAgICBhbGxFcXVhbCA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gYWxsRXF1YWwgJiYgYS5zaXplID09PSBiU2l6ZTtcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKFJlcGVhdCwgSW5kZXhlZFNlcSk7XG5cbiAgICBmdW5jdGlvbiBSZXBlYXQodmFsdWUsIHRpbWVzKSB7XG4gICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUmVwZWF0KSkge1xuICAgICAgICByZXR1cm4gbmV3IFJlcGVhdCh2YWx1ZSwgdGltZXMpO1xuICAgICAgfVxuICAgICAgdGhpcy5fdmFsdWUgPSB2YWx1ZTtcbiAgICAgIHRoaXMuc2l6ZSA9IHRpbWVzID09PSB1bmRlZmluZWQgPyBJbmZpbml0eSA6IE1hdGgubWF4KDAsIHRpbWVzKTtcbiAgICAgIGlmICh0aGlzLnNpemUgPT09IDApIHtcbiAgICAgICAgaWYgKEVNUFRZX1JFUEVBVCkge1xuICAgICAgICAgIHJldHVybiBFTVBUWV9SRVBFQVQ7XG4gICAgICAgIH1cbiAgICAgICAgRU1QVFlfUkVQRUFUID0gdGhpcztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBSZXBlYXQucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5zaXplID09PSAwKSB7XG4gICAgICAgIHJldHVybiAnUmVwZWF0IFtdJztcbiAgICAgIH1cbiAgICAgIHJldHVybiAnUmVwZWF0IFsgJyArIHRoaXMuX3ZhbHVlICsgJyAnICsgdGhpcy5zaXplICsgJyB0aW1lcyBdJztcbiAgICB9O1xuXG4gICAgUmVwZWF0LnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihpbmRleCwgbm90U2V0VmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmhhcyhpbmRleCkgPyB0aGlzLl92YWx1ZSA6IG5vdFNldFZhbHVlO1xuICAgIH07XG5cbiAgICBSZXBlYXQucHJvdG90eXBlLmluY2x1ZGVzID0gZnVuY3Rpb24oc2VhcmNoVmFsdWUpIHtcbiAgICAgIHJldHVybiBpcyh0aGlzLl92YWx1ZSwgc2VhcmNoVmFsdWUpO1xuICAgIH07XG5cbiAgICBSZXBlYXQucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24oYmVnaW4sIGVuZCkge1xuICAgICAgdmFyIHNpemUgPSB0aGlzLnNpemU7XG4gICAgICByZXR1cm4gd2hvbGVTbGljZShiZWdpbiwgZW5kLCBzaXplKSA/IHRoaXMgOlxuICAgICAgICBuZXcgUmVwZWF0KHRoaXMuX3ZhbHVlLCByZXNvbHZlRW5kKGVuZCwgc2l6ZSkgLSByZXNvbHZlQmVnaW4oYmVnaW4sIHNpemUpKTtcbiAgICB9O1xuXG4gICAgUmVwZWF0LnByb3RvdHlwZS5yZXZlcnNlID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgUmVwZWF0LnByb3RvdHlwZS5pbmRleE9mID0gZnVuY3Rpb24oc2VhcmNoVmFsdWUpIHtcbiAgICAgIGlmIChpcyh0aGlzLl92YWx1ZSwgc2VhcmNoVmFsdWUpKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgICAgcmV0dXJuIC0xO1xuICAgIH07XG5cbiAgICBSZXBlYXQucHJvdG90eXBlLmxhc3RJbmRleE9mID0gZnVuY3Rpb24oc2VhcmNoVmFsdWUpIHtcbiAgICAgIGlmIChpcyh0aGlzLl92YWx1ZSwgc2VhcmNoVmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNpemU7XG4gICAgICB9XG4gICAgICByZXR1cm4gLTE7XG4gICAgfTtcblxuICAgIFJlcGVhdC5wcm90b3R5cGUuX19pdGVyYXRlID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHtcbiAgICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCB0aGlzLnNpemU7IGlpKyspIHtcbiAgICAgICAgaWYgKGZuKHRoaXMuX3ZhbHVlLCBpaSwgdGhpcykgPT09IGZhbHNlKSB7XG4gICAgICAgICAgcmV0dXJuIGlpICsgMTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGlpO1xuICAgIH07XG5cbiAgICBSZXBlYXQucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICB2YXIgaWkgPSAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpIFxuICAgICAgICB7cmV0dXJuIGlpIDwgdGhpcyQwLnNpemUgPyBpdGVyYXRvclZhbHVlKHR5cGUsIGlpKyssIHRoaXMkMC5fdmFsdWUpIDogaXRlcmF0b3JEb25lKCl9XG4gICAgICApO1xuICAgIH07XG5cbiAgICBSZXBlYXQucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uKG90aGVyKSB7XG4gICAgICByZXR1cm4gb3RoZXIgaW5zdGFuY2VvZiBSZXBlYXQgP1xuICAgICAgICBpcyh0aGlzLl92YWx1ZSwgb3RoZXIuX3ZhbHVlKSA6XG4gICAgICAgIGRlZXBFcXVhbChvdGhlcik7XG4gICAgfTtcblxuXG4gIHZhciBFTVBUWV9SRVBFQVQ7XG5cbiAgZnVuY3Rpb24gaW52YXJpYW50KGNvbmRpdGlvbiwgZXJyb3IpIHtcbiAgICBpZiAoIWNvbmRpdGlvbikgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKFJhbmdlLCBJbmRleGVkU2VxKTtcblxuICAgIGZ1bmN0aW9uIFJhbmdlKHN0YXJ0LCBlbmQsIHN0ZXApIHtcbiAgICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBSYW5nZSkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSYW5nZShzdGFydCwgZW5kLCBzdGVwKTtcbiAgICAgIH1cbiAgICAgIGludmFyaWFudChzdGVwICE9PSAwLCAnQ2Fubm90IHN0ZXAgYSBSYW5nZSBieSAwJyk7XG4gICAgICBzdGFydCA9IHN0YXJ0IHx8IDA7XG4gICAgICBpZiAoZW5kID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZW5kID0gSW5maW5pdHk7XG4gICAgICB9XG4gICAgICBzdGVwID0gc3RlcCA9PT0gdW5kZWZpbmVkID8gMSA6IE1hdGguYWJzKHN0ZXApO1xuICAgICAgaWYgKGVuZCA8IHN0YXJ0KSB7XG4gICAgICAgIHN0ZXAgPSAtc3RlcDtcbiAgICAgIH1cbiAgICAgIHRoaXMuX3N0YXJ0ID0gc3RhcnQ7XG4gICAgICB0aGlzLl9lbmQgPSBlbmQ7XG4gICAgICB0aGlzLl9zdGVwID0gc3RlcDtcbiAgICAgIHRoaXMuc2l6ZSA9IE1hdGgubWF4KDAsIE1hdGguY2VpbCgoZW5kIC0gc3RhcnQpIC8gc3RlcCAtIDEpICsgMSk7XG4gICAgICBpZiAodGhpcy5zaXplID09PSAwKSB7XG4gICAgICAgIGlmIChFTVBUWV9SQU5HRSkge1xuICAgICAgICAgIHJldHVybiBFTVBUWV9SQU5HRTtcbiAgICAgICAgfVxuICAgICAgICBFTVBUWV9SQU5HRSA9IHRoaXM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgUmFuZ2UucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5zaXplID09PSAwKSB7XG4gICAgICAgIHJldHVybiAnUmFuZ2UgW10nO1xuICAgICAgfVxuICAgICAgcmV0dXJuICdSYW5nZSBbICcgK1xuICAgICAgICB0aGlzLl9zdGFydCArICcuLi4nICsgdGhpcy5fZW5kICtcbiAgICAgICAgKHRoaXMuX3N0ZXAgPiAxID8gJyBieSAnICsgdGhpcy5fc3RlcCA6ICcnKSArXG4gICAgICAnIF0nO1xuICAgIH07XG5cbiAgICBSYW5nZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oaW5kZXgsIG5vdFNldFZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5oYXMoaW5kZXgpID9cbiAgICAgICAgdGhpcy5fc3RhcnQgKyB3cmFwSW5kZXgodGhpcywgaW5kZXgpICogdGhpcy5fc3RlcCA6XG4gICAgICAgIG5vdFNldFZhbHVlO1xuICAgIH07XG5cbiAgICBSYW5nZS5wcm90b3R5cGUuaW5jbHVkZXMgPSBmdW5jdGlvbihzZWFyY2hWYWx1ZSkge1xuICAgICAgdmFyIHBvc3NpYmxlSW5kZXggPSAoc2VhcmNoVmFsdWUgLSB0aGlzLl9zdGFydCkgLyB0aGlzLl9zdGVwO1xuICAgICAgcmV0dXJuIHBvc3NpYmxlSW5kZXggPj0gMCAmJlxuICAgICAgICBwb3NzaWJsZUluZGV4IDwgdGhpcy5zaXplICYmXG4gICAgICAgIHBvc3NpYmxlSW5kZXggPT09IE1hdGguZmxvb3IocG9zc2libGVJbmRleCk7XG4gICAgfTtcblxuICAgIFJhbmdlLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcbiAgICAgIGlmICh3aG9sZVNsaWNlKGJlZ2luLCBlbmQsIHRoaXMuc2l6ZSkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICBiZWdpbiA9IHJlc29sdmVCZWdpbihiZWdpbiwgdGhpcy5zaXplKTtcbiAgICAgIGVuZCA9IHJlc29sdmVFbmQoZW5kLCB0aGlzLnNpemUpO1xuICAgICAgaWYgKGVuZCA8PSBiZWdpbikge1xuICAgICAgICByZXR1cm4gbmV3IFJhbmdlKDAsIDApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBSYW5nZSh0aGlzLmdldChiZWdpbiwgdGhpcy5fZW5kKSwgdGhpcy5nZXQoZW5kLCB0aGlzLl9lbmQpLCB0aGlzLl9zdGVwKTtcbiAgICB9O1xuXG4gICAgUmFuZ2UucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbihzZWFyY2hWYWx1ZSkge1xuICAgICAgdmFyIG9mZnNldFZhbHVlID0gc2VhcmNoVmFsdWUgLSB0aGlzLl9zdGFydDtcbiAgICAgIGlmIChvZmZzZXRWYWx1ZSAlIHRoaXMuX3N0ZXAgPT09IDApIHtcbiAgICAgICAgdmFyIGluZGV4ID0gb2Zmc2V0VmFsdWUgLyB0aGlzLl9zdGVwO1xuICAgICAgICBpZiAoaW5kZXggPj0gMCAmJiBpbmRleCA8IHRoaXMuc2l6ZSkge1xuICAgICAgICAgIHJldHVybiBpbmRleFxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gLTE7XG4gICAgfTtcblxuICAgIFJhbmdlLnByb3RvdHlwZS5sYXN0SW5kZXhPZiA9IGZ1bmN0aW9uKHNlYXJjaFZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5pbmRleE9mKHNlYXJjaFZhbHVlKTtcbiAgICB9O1xuXG4gICAgUmFuZ2UucHJvdG90eXBlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7XG4gICAgICB2YXIgbWF4SW5kZXggPSB0aGlzLnNpemUgLSAxO1xuICAgICAgdmFyIHN0ZXAgPSB0aGlzLl9zdGVwO1xuICAgICAgdmFyIHZhbHVlID0gcmV2ZXJzZSA/IHRoaXMuX3N0YXJ0ICsgbWF4SW5kZXggKiBzdGVwIDogdGhpcy5fc3RhcnQ7XG4gICAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDw9IG1heEluZGV4OyBpaSsrKSB7XG4gICAgICAgIGlmIChmbih2YWx1ZSwgaWksIHRoaXMpID09PSBmYWxzZSkge1xuICAgICAgICAgIHJldHVybiBpaSArIDE7XG4gICAgICAgIH1cbiAgICAgICAgdmFsdWUgKz0gcmV2ZXJzZSA/IC1zdGVwIDogc3RlcDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpaTtcbiAgICB9O1xuXG4gICAgUmFuZ2UucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICB2YXIgbWF4SW5kZXggPSB0aGlzLnNpemUgLSAxO1xuICAgICAgdmFyIHN0ZXAgPSB0aGlzLl9zdGVwO1xuICAgICAgdmFyIHZhbHVlID0gcmV2ZXJzZSA/IHRoaXMuX3N0YXJ0ICsgbWF4SW5kZXggKiBzdGVwIDogdGhpcy5fc3RhcnQ7XG4gICAgICB2YXIgaWkgPSAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHZhciB2ID0gdmFsdWU7XG4gICAgICAgIHZhbHVlICs9IHJldmVyc2UgPyAtc3RlcCA6IHN0ZXA7XG4gICAgICAgIHJldHVybiBpaSA+IG1heEluZGV4ID8gaXRlcmF0b3JEb25lKCkgOiBpdGVyYXRvclZhbHVlKHR5cGUsIGlpKyssIHYpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIFJhbmdlLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbihvdGhlcikge1xuICAgICAgcmV0dXJuIG90aGVyIGluc3RhbmNlb2YgUmFuZ2UgP1xuICAgICAgICB0aGlzLl9zdGFydCA9PT0gb3RoZXIuX3N0YXJ0ICYmXG4gICAgICAgIHRoaXMuX2VuZCA9PT0gb3RoZXIuX2VuZCAmJlxuICAgICAgICB0aGlzLl9zdGVwID09PSBvdGhlci5fc3RlcCA6XG4gICAgICAgIGRlZXBFcXVhbCh0aGlzLCBvdGhlcik7XG4gICAgfTtcblxuXG4gIHZhciBFTVBUWV9SQU5HRTtcblxuICBjcmVhdGVDbGFzcyhDb2xsZWN0aW9uLCBJdGVyYWJsZSk7XG4gICAgZnVuY3Rpb24gQ29sbGVjdGlvbigpIHtcbiAgICAgIHRocm93IFR5cGVFcnJvcignQWJzdHJhY3QnKTtcbiAgICB9XG5cblxuICBjcmVhdGVDbGFzcyhLZXllZENvbGxlY3Rpb24sIENvbGxlY3Rpb24pO2Z1bmN0aW9uIEtleWVkQ29sbGVjdGlvbigpIHt9XG5cbiAgY3JlYXRlQ2xhc3MoSW5kZXhlZENvbGxlY3Rpb24sIENvbGxlY3Rpb24pO2Z1bmN0aW9uIEluZGV4ZWRDb2xsZWN0aW9uKCkge31cblxuICBjcmVhdGVDbGFzcyhTZXRDb2xsZWN0aW9uLCBDb2xsZWN0aW9uKTtmdW5jdGlvbiBTZXRDb2xsZWN0aW9uKCkge31cblxuXG4gIENvbGxlY3Rpb24uS2V5ZWQgPSBLZXllZENvbGxlY3Rpb247XG4gIENvbGxlY3Rpb24uSW5kZXhlZCA9IEluZGV4ZWRDb2xsZWN0aW9uO1xuICBDb2xsZWN0aW9uLlNldCA9IFNldENvbGxlY3Rpb247XG5cbiAgdmFyIGltdWwgPVxuICAgIHR5cGVvZiBNYXRoLmltdWwgPT09ICdmdW5jdGlvbicgJiYgTWF0aC5pbXVsKDB4ZmZmZmZmZmYsIDIpID09PSAtMiA/XG4gICAgTWF0aC5pbXVsIDpcbiAgICBmdW5jdGlvbiBpbXVsKGEsIGIpIHtcbiAgICAgIGEgPSBhIHwgMDsgLy8gaW50XG4gICAgICBiID0gYiB8IDA7IC8vIGludFxuICAgICAgdmFyIGMgPSBhICYgMHhmZmZmO1xuICAgICAgdmFyIGQgPSBiICYgMHhmZmZmO1xuICAgICAgLy8gU2hpZnQgYnkgMCBmaXhlcyB0aGUgc2lnbiBvbiB0aGUgaGlnaCBwYXJ0LlxuICAgICAgcmV0dXJuIChjICogZCkgKyAoKCgoYSA+Pj4gMTYpICogZCArIGMgKiAoYiA+Pj4gMTYpKSA8PCAxNikgPj4+IDApIHwgMDsgLy8gaW50XG4gICAgfTtcblxuICAvLyB2OCBoYXMgYW4gb3B0aW1pemF0aW9uIGZvciBzdG9yaW5nIDMxLWJpdCBzaWduZWQgbnVtYmVycy5cbiAgLy8gVmFsdWVzIHdoaWNoIGhhdmUgZWl0aGVyIDAwIG9yIDExIGFzIHRoZSBoaWdoIG9yZGVyIGJpdHMgcXVhbGlmeS5cbiAgLy8gVGhpcyBmdW5jdGlvbiBkcm9wcyB0aGUgaGlnaGVzdCBvcmRlciBiaXQgaW4gYSBzaWduZWQgbnVtYmVyLCBtYWludGFpbmluZ1xuICAvLyB0aGUgc2lnbiBiaXQuXG4gIGZ1bmN0aW9uIHNtaShpMzIpIHtcbiAgICByZXR1cm4gKChpMzIgPj4+IDEpICYgMHg0MDAwMDAwMCkgfCAoaTMyICYgMHhCRkZGRkZGRik7XG4gIH1cblxuICBmdW5jdGlvbiBoYXNoKG8pIHtcbiAgICBpZiAobyA9PT0gZmFsc2UgfHwgbyA9PT0gbnVsbCB8fCBvID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIG8udmFsdWVPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgbyA9IG8udmFsdWVPZigpO1xuICAgICAgaWYgKG8gPT09IGZhbHNlIHx8IG8gPT09IG51bGwgfHwgbyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAobyA9PT0gdHJ1ZSkge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICAgIHZhciB0eXBlID0gdHlwZW9mIG87XG4gICAgaWYgKHR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICB2YXIgaCA9IG8gfCAwO1xuICAgICAgaWYgKGggIT09IG8pIHtcbiAgICAgICAgaCBePSBvICogMHhGRkZGRkZGRjtcbiAgICAgIH1cbiAgICAgIHdoaWxlIChvID4gMHhGRkZGRkZGRikge1xuICAgICAgICBvIC89IDB4RkZGRkZGRkY7XG4gICAgICAgIGggXj0gbztcbiAgICAgIH1cbiAgICAgIHJldHVybiBzbWkoaCk7XG4gICAgfVxuICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIG8ubGVuZ3RoID4gU1RSSU5HX0hBU0hfQ0FDSEVfTUlOX1NUUkxFTiA/IGNhY2hlZEhhc2hTdHJpbmcobykgOiBoYXNoU3RyaW5nKG8pO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIG8uaGFzaENvZGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiBvLmhhc2hDb2RlKCk7XG4gICAgfVxuICAgIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgcmV0dXJuIGhhc2hKU09iaihvKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBvLnRvU3RyaW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gaGFzaFN0cmluZyhvLnRvU3RyaW5nKCkpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1ZhbHVlIHR5cGUgJyArIHR5cGUgKyAnIGNhbm5vdCBiZSBoYXNoZWQuJyk7XG4gIH1cblxuICBmdW5jdGlvbiBjYWNoZWRIYXNoU3RyaW5nKHN0cmluZykge1xuICAgIHZhciBoYXNoID0gc3RyaW5nSGFzaENhY2hlW3N0cmluZ107XG4gICAgaWYgKGhhc2ggPT09IHVuZGVmaW5lZCkge1xuICAgICAgaGFzaCA9IGhhc2hTdHJpbmcoc3RyaW5nKTtcbiAgICAgIGlmIChTVFJJTkdfSEFTSF9DQUNIRV9TSVpFID09PSBTVFJJTkdfSEFTSF9DQUNIRV9NQVhfU0laRSkge1xuICAgICAgICBTVFJJTkdfSEFTSF9DQUNIRV9TSVpFID0gMDtcbiAgICAgICAgc3RyaW5nSGFzaENhY2hlID0ge307XG4gICAgICB9XG4gICAgICBTVFJJTkdfSEFTSF9DQUNIRV9TSVpFKys7XG4gICAgICBzdHJpbmdIYXNoQ2FjaGVbc3RyaW5nXSA9IGhhc2g7XG4gICAgfVxuICAgIHJldHVybiBoYXNoO1xuICB9XG5cbiAgLy8gaHR0cDovL2pzcGVyZi5jb20vaGFzaGluZy1zdHJpbmdzXG4gIGZ1bmN0aW9uIGhhc2hTdHJpbmcoc3RyaW5nKSB7XG4gICAgLy8gVGhpcyBpcyB0aGUgaGFzaCBmcm9tIEpWTVxuICAgIC8vIFRoZSBoYXNoIGNvZGUgZm9yIGEgc3RyaW5nIGlzIGNvbXB1dGVkIGFzXG4gICAgLy8gc1swXSAqIDMxIF4gKG4gLSAxKSArIHNbMV0gKiAzMSBeIChuIC0gMikgKyAuLi4gKyBzW24gLSAxXSxcbiAgICAvLyB3aGVyZSBzW2ldIGlzIHRoZSBpdGggY2hhcmFjdGVyIG9mIHRoZSBzdHJpbmcgYW5kIG4gaXMgdGhlIGxlbmd0aCBvZlxuICAgIC8vIHRoZSBzdHJpbmcuIFdlIFwibW9kXCIgdGhlIHJlc3VsdCB0byBtYWtlIGl0IGJldHdlZW4gMCAoaW5jbHVzaXZlKSBhbmQgMl4zMVxuICAgIC8vIChleGNsdXNpdmUpIGJ5IGRyb3BwaW5nIGhpZ2ggYml0cy5cbiAgICB2YXIgaGFzaCA9IDA7XG4gICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IHN0cmluZy5sZW5ndGg7IGlpKyspIHtcbiAgICAgIGhhc2ggPSAzMSAqIGhhc2ggKyBzdHJpbmcuY2hhckNvZGVBdChpaSkgfCAwO1xuICAgIH1cbiAgICByZXR1cm4gc21pKGhhc2gpO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFzaEpTT2JqKG9iaikge1xuICAgIHZhciBoYXNoO1xuICAgIGlmICh1c2luZ1dlYWtNYXApIHtcbiAgICAgIGhhc2ggPSB3ZWFrTWFwLmdldChvYmopO1xuICAgICAgaWYgKGhhc2ggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gaGFzaDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBoYXNoID0gb2JqW1VJRF9IQVNIX0tFWV07XG4gICAgaWYgKGhhc2ggIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGhhc2g7XG4gICAgfVxuXG4gICAgaWYgKCFjYW5EZWZpbmVQcm9wZXJ0eSkge1xuICAgICAgaGFzaCA9IG9iai5wcm9wZXJ0eUlzRW51bWVyYWJsZSAmJiBvYmoucHJvcGVydHlJc0VudW1lcmFibGVbVUlEX0hBU0hfS0VZXTtcbiAgICAgIGlmIChoYXNoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGhhc2g7XG4gICAgICB9XG5cbiAgICAgIGhhc2ggPSBnZXRJRU5vZGVIYXNoKG9iaik7XG4gICAgICBpZiAoaGFzaCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBoYXNoO1xuICAgICAgfVxuICAgIH1cblxuICAgIGhhc2ggPSArK29iakhhc2hVSUQ7XG4gICAgaWYgKG9iakhhc2hVSUQgJiAweDQwMDAwMDAwKSB7XG4gICAgICBvYmpIYXNoVUlEID0gMDtcbiAgICB9XG5cbiAgICBpZiAodXNpbmdXZWFrTWFwKSB7XG4gICAgICB3ZWFrTWFwLnNldChvYmosIGhhc2gpO1xuICAgIH0gZWxzZSBpZiAoaXNFeHRlbnNpYmxlICE9PSB1bmRlZmluZWQgJiYgaXNFeHRlbnNpYmxlKG9iaikgPT09IGZhbHNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vbi1leHRlbnNpYmxlIG9iamVjdHMgYXJlIG5vdCBhbGxvd2VkIGFzIGtleXMuJyk7XG4gICAgfSBlbHNlIGlmIChjYW5EZWZpbmVQcm9wZXJ0eSkge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwgVUlEX0hBU0hfS0VZLCB7XG4gICAgICAgICdlbnVtZXJhYmxlJzogZmFsc2UsXG4gICAgICAgICdjb25maWd1cmFibGUnOiBmYWxzZSxcbiAgICAgICAgJ3dyaXRhYmxlJzogZmFsc2UsXG4gICAgICAgICd2YWx1ZSc6IGhhc2hcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAob2JqLnByb3BlcnR5SXNFbnVtZXJhYmxlICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgICAgIG9iai5wcm9wZXJ0eUlzRW51bWVyYWJsZSA9PT0gb2JqLmNvbnN0cnVjdG9yLnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZSkge1xuICAgICAgLy8gU2luY2Ugd2UgY2FuJ3QgZGVmaW5lIGEgbm9uLWVudW1lcmFibGUgcHJvcGVydHkgb24gdGhlIG9iamVjdFxuICAgICAgLy8gd2UnbGwgaGlqYWNrIG9uZSBvZiB0aGUgbGVzcy11c2VkIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXMgdG9cbiAgICAgIC8vIHNhdmUgb3VyIGhhc2ggb24gaXQuIFNpbmNlIHRoaXMgaXMgYSBmdW5jdGlvbiBpdCB3aWxsIG5vdCBzaG93IHVwIGluXG4gICAgICAvLyBgSlNPTi5zdHJpbmdpZnlgIHdoaWNoIGlzIHdoYXQgd2Ugd2FudC5cbiAgICAgIG9iai5wcm9wZXJ0eUlzRW51bWVyYWJsZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgICBvYmoucHJvcGVydHlJc0VudW1lcmFibGVbVUlEX0hBU0hfS0VZXSA9IGhhc2g7XG4gICAgfSBlbHNlIGlmIChvYmoubm9kZVR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gQXQgdGhpcyBwb2ludCB3ZSBjb3VsZG4ndCBnZXQgdGhlIElFIGB1bmlxdWVJRGAgdG8gdXNlIGFzIGEgaGFzaFxuICAgICAgLy8gYW5kIHdlIGNvdWxkbid0IHVzZSBhIG5vbi1lbnVtZXJhYmxlIHByb3BlcnR5IHRvIGV4cGxvaXQgdGhlXG4gICAgICAvLyBkb250RW51bSBidWcgc28gd2Ugc2ltcGx5IGFkZCB0aGUgYFVJRF9IQVNIX0tFWWAgb24gdGhlIG5vZGVcbiAgICAgIC8vIGl0c2VsZi5cbiAgICAgIG9ialtVSURfSEFTSF9LRVldID0gaGFzaDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gc2V0IGEgbm9uLWVudW1lcmFibGUgcHJvcGVydHkgb24gb2JqZWN0LicpO1xuICAgIH1cblxuICAgIHJldHVybiBoYXNoO1xuICB9XG5cbiAgLy8gR2V0IHJlZmVyZW5jZXMgdG8gRVM1IG9iamVjdCBtZXRob2RzLlxuICB2YXIgaXNFeHRlbnNpYmxlID0gT2JqZWN0LmlzRXh0ZW5zaWJsZTtcblxuICAvLyBUcnVlIGlmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSB3b3JrcyBhcyBleHBlY3RlZC4gSUU4IGZhaWxzIHRoaXMgdGVzdC5cbiAgdmFyIGNhbkRlZmluZVByb3BlcnR5ID0gKGZ1bmN0aW9uKCkge1xuICAgIHRyeSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdAJywge30pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSgpKTtcblxuICAvLyBJRSBoYXMgYSBgdW5pcXVlSURgIHByb3BlcnR5IG9uIERPTSBub2Rlcy4gV2UgY2FuIGNvbnN0cnVjdCB0aGUgaGFzaCBmcm9tIGl0XG4gIC8vIGFuZCBhdm9pZCBtZW1vcnkgbGVha3MgZnJvbSB0aGUgSUUgY2xvbmVOb2RlIGJ1Zy5cbiAgZnVuY3Rpb24gZ2V0SUVOb2RlSGFzaChub2RlKSB7XG4gICAgaWYgKG5vZGUgJiYgbm9kZS5ub2RlVHlwZSA+IDApIHtcbiAgICAgIHN3aXRjaCAobm9kZS5ub2RlVHlwZSkge1xuICAgICAgICBjYXNlIDE6IC8vIEVsZW1lbnRcbiAgICAgICAgICByZXR1cm4gbm9kZS51bmlxdWVJRDtcbiAgICAgICAgY2FzZSA5OiAvLyBEb2N1bWVudFxuICAgICAgICAgIHJldHVybiBub2RlLmRvY3VtZW50RWxlbWVudCAmJiBub2RlLmRvY3VtZW50RWxlbWVudC51bmlxdWVJRDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBJZiBwb3NzaWJsZSwgdXNlIGEgV2Vha01hcC5cbiAgdmFyIHVzaW5nV2Vha01hcCA9IHR5cGVvZiBXZWFrTWFwID09PSAnZnVuY3Rpb24nO1xuICB2YXIgd2Vha01hcDtcbiAgaWYgKHVzaW5nV2Vha01hcCkge1xuICAgIHdlYWtNYXAgPSBuZXcgV2Vha01hcCgpO1xuICB9XG5cbiAgdmFyIG9iakhhc2hVSUQgPSAwO1xuXG4gIHZhciBVSURfSEFTSF9LRVkgPSAnX19pbW11dGFibGVoYXNoX18nO1xuICBpZiAodHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIFVJRF9IQVNIX0tFWSA9IFN5bWJvbChVSURfSEFTSF9LRVkpO1xuICB9XG5cbiAgdmFyIFNUUklOR19IQVNIX0NBQ0hFX01JTl9TVFJMRU4gPSAxNjtcbiAgdmFyIFNUUklOR19IQVNIX0NBQ0hFX01BWF9TSVpFID0gMjU1O1xuICB2YXIgU1RSSU5HX0hBU0hfQ0FDSEVfU0laRSA9IDA7XG4gIHZhciBzdHJpbmdIYXNoQ2FjaGUgPSB7fTtcblxuICBmdW5jdGlvbiBhc3NlcnROb3RJbmZpbml0ZShzaXplKSB7XG4gICAgaW52YXJpYW50KFxuICAgICAgc2l6ZSAhPT0gSW5maW5pdHksXG4gICAgICAnQ2Fubm90IHBlcmZvcm0gdGhpcyBhY3Rpb24gd2l0aCBhbiBpbmZpbml0ZSBzaXplLidcbiAgICApO1xuICB9XG5cbiAgY3JlYXRlQ2xhc3MoTWFwLCBLZXllZENvbGxlY3Rpb24pO1xuXG4gICAgLy8gQHByYWdtYSBDb25zdHJ1Y3Rpb25cblxuICAgIGZ1bmN0aW9uIE1hcCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgPyBlbXB0eU1hcCgpIDpcbiAgICAgICAgaXNNYXAodmFsdWUpICYmICFpc09yZGVyZWQodmFsdWUpID8gdmFsdWUgOlxuICAgICAgICBlbXB0eU1hcCgpLndpdGhNdXRhdGlvbnMoZnVuY3Rpb24obWFwICkge1xuICAgICAgICAgIHZhciBpdGVyID0gS2V5ZWRJdGVyYWJsZSh2YWx1ZSk7XG4gICAgICAgICAgYXNzZXJ0Tm90SW5maW5pdGUoaXRlci5zaXplKTtcbiAgICAgICAgICBpdGVyLmZvckVhY2goZnVuY3Rpb24odiwgaykgIHtyZXR1cm4gbWFwLnNldChrLCB2KX0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBNYXAucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fX3RvU3RyaW5nKCdNYXAgeycsICd9Jyk7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgQWNjZXNzXG5cbiAgICBNYXAucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKGssIG5vdFNldFZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5fcm9vdCA/XG4gICAgICAgIHRoaXMuX3Jvb3QuZ2V0KDAsIHVuZGVmaW5lZCwgaywgbm90U2V0VmFsdWUpIDpcbiAgICAgICAgbm90U2V0VmFsdWU7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgTW9kaWZpY2F0aW9uXG5cbiAgICBNYXAucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKGssIHYpIHtcbiAgICAgIHJldHVybiB1cGRhdGVNYXAodGhpcywgaywgdik7XG4gICAgfTtcblxuICAgIE1hcC5wcm90b3R5cGUuc2V0SW4gPSBmdW5jdGlvbihrZXlQYXRoLCB2KSB7XG4gICAgICByZXR1cm4gdGhpcy51cGRhdGVJbihrZXlQYXRoLCBOT1RfU0VULCBmdW5jdGlvbigpICB7cmV0dXJuIHZ9KTtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbihrKSB7XG4gICAgICByZXR1cm4gdXBkYXRlTWFwKHRoaXMsIGssIE5PVF9TRVQpO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLmRlbGV0ZUluID0gZnVuY3Rpb24oa2V5UGF0aCkge1xuICAgICAgcmV0dXJuIHRoaXMudXBkYXRlSW4oa2V5UGF0aCwgZnVuY3Rpb24oKSAge3JldHVybiBOT1RfU0VUfSk7XG4gICAgfTtcblxuICAgIE1hcC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24oaywgbm90U2V0VmFsdWUsIHVwZGF0ZXIpIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09PSAxID9cbiAgICAgICAgayh0aGlzKSA6XG4gICAgICAgIHRoaXMudXBkYXRlSW4oW2tdLCBub3RTZXRWYWx1ZSwgdXBkYXRlcik7XG4gICAgfTtcblxuICAgIE1hcC5wcm90b3R5cGUudXBkYXRlSW4gPSBmdW5jdGlvbihrZXlQYXRoLCBub3RTZXRWYWx1ZSwgdXBkYXRlcikge1xuICAgICAgaWYgKCF1cGRhdGVyKSB7XG4gICAgICAgIHVwZGF0ZXIgPSBub3RTZXRWYWx1ZTtcbiAgICAgICAgbm90U2V0VmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICB2YXIgdXBkYXRlZFZhbHVlID0gdXBkYXRlSW5EZWVwTWFwKFxuICAgICAgICB0aGlzLFxuICAgICAgICBmb3JjZUl0ZXJhdG9yKGtleVBhdGgpLFxuICAgICAgICBub3RTZXRWYWx1ZSxcbiAgICAgICAgdXBkYXRlclxuICAgICAgKTtcbiAgICAgIHJldHVybiB1cGRhdGVkVmFsdWUgPT09IE5PVF9TRVQgPyB1bmRlZmluZWQgOiB1cGRhdGVkVmFsdWU7XG4gICAgfTtcblxuICAgIE1hcC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLnNpemUgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5fX293bmVySUQpIHtcbiAgICAgICAgdGhpcy5zaXplID0gMDtcbiAgICAgICAgdGhpcy5fcm9vdCA9IG51bGw7XG4gICAgICAgIHRoaXMuX19oYXNoID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9fYWx0ZXJlZCA9IHRydWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGVtcHR5TWFwKCk7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgQ29tcG9zaXRpb25cblxuICAgIE1hcC5wcm90b3R5cGUubWVyZ2UgPSBmdW5jdGlvbigvKi4uLml0ZXJzKi8pIHtcbiAgICAgIHJldHVybiBtZXJnZUludG9NYXBXaXRoKHRoaXMsIHVuZGVmaW5lZCwgYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5tZXJnZVdpdGggPSBmdW5jdGlvbihtZXJnZXIpIHt2YXIgaXRlcnMgPSBTTElDRSQwLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgIHJldHVybiBtZXJnZUludG9NYXBXaXRoKHRoaXMsIG1lcmdlciwgaXRlcnMpO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLm1lcmdlSW4gPSBmdW5jdGlvbihrZXlQYXRoKSB7dmFyIGl0ZXJzID0gU0xJQ0UkMC5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICByZXR1cm4gdGhpcy51cGRhdGVJbihcbiAgICAgICAga2V5UGF0aCxcbiAgICAgICAgZW1wdHlNYXAoKSxcbiAgICAgICAgZnVuY3Rpb24obSApIHtyZXR1cm4gdHlwZW9mIG0ubWVyZ2UgPT09ICdmdW5jdGlvbicgP1xuICAgICAgICAgIG0ubWVyZ2UuYXBwbHkobSwgaXRlcnMpIDpcbiAgICAgICAgICBpdGVyc1tpdGVycy5sZW5ndGggLSAxXX1cbiAgICAgICk7XG4gICAgfTtcblxuICAgIE1hcC5wcm90b3R5cGUubWVyZ2VEZWVwID0gZnVuY3Rpb24oLyouLi5pdGVycyovKSB7XG4gICAgICByZXR1cm4gbWVyZ2VJbnRvTWFwV2l0aCh0aGlzLCBkZWVwTWVyZ2VyLCBhcmd1bWVudHMpO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLm1lcmdlRGVlcFdpdGggPSBmdW5jdGlvbihtZXJnZXIpIHt2YXIgaXRlcnMgPSBTTElDRSQwLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgIHJldHVybiBtZXJnZUludG9NYXBXaXRoKHRoaXMsIGRlZXBNZXJnZXJXaXRoKG1lcmdlciksIGl0ZXJzKTtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5tZXJnZURlZXBJbiA9IGZ1bmN0aW9uKGtleVBhdGgpIHt2YXIgaXRlcnMgPSBTTElDRSQwLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgIHJldHVybiB0aGlzLnVwZGF0ZUluKFxuICAgICAgICBrZXlQYXRoLFxuICAgICAgICBlbXB0eU1hcCgpLFxuICAgICAgICBmdW5jdGlvbihtICkge3JldHVybiB0eXBlb2YgbS5tZXJnZURlZXAgPT09ICdmdW5jdGlvbicgP1xuICAgICAgICAgIG0ubWVyZ2VEZWVwLmFwcGx5KG0sIGl0ZXJzKSA6XG4gICAgICAgICAgaXRlcnNbaXRlcnMubGVuZ3RoIC0gMV19XG4gICAgICApO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLnNvcnQgPSBmdW5jdGlvbihjb21wYXJhdG9yKSB7XG4gICAgICAvLyBMYXRlIGJpbmRpbmdcbiAgICAgIHJldHVybiBPcmRlcmVkTWFwKHNvcnRGYWN0b3J5KHRoaXMsIGNvbXBhcmF0b3IpKTtcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5zb3J0QnkgPSBmdW5jdGlvbihtYXBwZXIsIGNvbXBhcmF0b3IpIHtcbiAgICAgIC8vIExhdGUgYmluZGluZ1xuICAgICAgcmV0dXJuIE9yZGVyZWRNYXAoc29ydEZhY3RvcnkodGhpcywgY29tcGFyYXRvciwgbWFwcGVyKSk7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgTXV0YWJpbGl0eVxuXG4gICAgTWFwLnByb3RvdHlwZS53aXRoTXV0YXRpb25zID0gZnVuY3Rpb24oZm4pIHtcbiAgICAgIHZhciBtdXRhYmxlID0gdGhpcy5hc011dGFibGUoKTtcbiAgICAgIGZuKG11dGFibGUpO1xuICAgICAgcmV0dXJuIG11dGFibGUud2FzQWx0ZXJlZCgpID8gbXV0YWJsZS5fX2Vuc3VyZU93bmVyKHRoaXMuX19vd25lcklEKSA6IHRoaXM7XG4gICAgfTtcblxuICAgIE1hcC5wcm90b3R5cGUuYXNNdXRhYmxlID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fX293bmVySUQgPyB0aGlzIDogdGhpcy5fX2Vuc3VyZU93bmVyKG5ldyBPd25lcklEKCkpO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLmFzSW1tdXRhYmxlID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fX2Vuc3VyZU93bmVyKCk7XG4gICAgfTtcblxuICAgIE1hcC5wcm90b3R5cGUud2FzQWx0ZXJlZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX19hbHRlcmVkO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICByZXR1cm4gbmV3IE1hcEl0ZXJhdG9yKHRoaXMsIHR5cGUsIHJldmVyc2UpO1xuICAgIH07XG5cbiAgICBNYXAucHJvdG90eXBlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICB0aGlzLl9yb290ICYmIHRoaXMuX3Jvb3QuaXRlcmF0ZShmdW5jdGlvbihlbnRyeSApIHtcbiAgICAgICAgaXRlcmF0aW9ucysrO1xuICAgICAgICByZXR1cm4gZm4oZW50cnlbMV0sIGVudHJ5WzBdLCB0aGlzJDApO1xuICAgICAgfSwgcmV2ZXJzZSk7XG4gICAgICByZXR1cm4gaXRlcmF0aW9ucztcbiAgICB9O1xuXG4gICAgTWFwLnByb3RvdHlwZS5fX2Vuc3VyZU93bmVyID0gZnVuY3Rpb24ob3duZXJJRCkge1xuICAgICAgaWYgKG93bmVySUQgPT09IHRoaXMuX19vd25lcklEKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgaWYgKCFvd25lcklEKSB7XG4gICAgICAgIHRoaXMuX19vd25lcklEID0gb3duZXJJRDtcbiAgICAgICAgdGhpcy5fX2FsdGVyZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWFrZU1hcCh0aGlzLnNpemUsIHRoaXMuX3Jvb3QsIG93bmVySUQsIHRoaXMuX19oYXNoKTtcbiAgICB9O1xuXG5cbiAgZnVuY3Rpb24gaXNNYXAobWF5YmVNYXApIHtcbiAgICByZXR1cm4gISEobWF5YmVNYXAgJiYgbWF5YmVNYXBbSVNfTUFQX1NFTlRJTkVMXSk7XG4gIH1cblxuICBNYXAuaXNNYXAgPSBpc01hcDtcblxuICB2YXIgSVNfTUFQX1NFTlRJTkVMID0gJ0BAX19JTU1VVEFCTEVfTUFQX19AQCc7XG5cbiAgdmFyIE1hcFByb3RvdHlwZSA9IE1hcC5wcm90b3R5cGU7XG4gIE1hcFByb3RvdHlwZVtJU19NQVBfU0VOVElORUxdID0gdHJ1ZTtcbiAgTWFwUHJvdG90eXBlW0RFTEVURV0gPSBNYXBQcm90b3R5cGUucmVtb3ZlO1xuICBNYXBQcm90b3R5cGUucmVtb3ZlSW4gPSBNYXBQcm90b3R5cGUuZGVsZXRlSW47XG5cblxuICAvLyAjcHJhZ21hIFRyaWUgTm9kZXNcblxuXG5cbiAgICBmdW5jdGlvbiBBcnJheU1hcE5vZGUob3duZXJJRCwgZW50cmllcykge1xuICAgICAgdGhpcy5vd25lcklEID0gb3duZXJJRDtcbiAgICAgIHRoaXMuZW50cmllcyA9IGVudHJpZXM7XG4gICAgfVxuXG4gICAgQXJyYXlNYXBOb2RlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihzaGlmdCwga2V5SGFzaCwga2V5LCBub3RTZXRWYWx1ZSkge1xuICAgICAgdmFyIGVudHJpZXMgPSB0aGlzLmVudHJpZXM7XG4gICAgICBmb3IgKHZhciBpaSA9IDAsIGxlbiA9IGVudHJpZXMubGVuZ3RoOyBpaSA8IGxlbjsgaWkrKykge1xuICAgICAgICBpZiAoaXMoa2V5LCBlbnRyaWVzW2lpXVswXSkpIHtcbiAgICAgICAgICByZXR1cm4gZW50cmllc1tpaV1bMV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBub3RTZXRWYWx1ZTtcbiAgICB9O1xuXG4gICAgQXJyYXlNYXBOb2RlLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbihvd25lcklELCBzaGlmdCwga2V5SGFzaCwga2V5LCB2YWx1ZSwgZGlkQ2hhbmdlU2l6ZSwgZGlkQWx0ZXIpIHtcbiAgICAgIHZhciByZW1vdmVkID0gdmFsdWUgPT09IE5PVF9TRVQ7XG5cbiAgICAgIHZhciBlbnRyaWVzID0gdGhpcy5lbnRyaWVzO1xuICAgICAgdmFyIGlkeCA9IDA7XG4gICAgICBmb3IgKHZhciBsZW4gPSBlbnRyaWVzLmxlbmd0aDsgaWR4IDwgbGVuOyBpZHgrKykge1xuICAgICAgICBpZiAoaXMoa2V5LCBlbnRyaWVzW2lkeF1bMF0pKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHZhciBleGlzdHMgPSBpZHggPCBsZW47XG5cbiAgICAgIGlmIChleGlzdHMgPyBlbnRyaWVzW2lkeF1bMV0gPT09IHZhbHVlIDogcmVtb3ZlZCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgU2V0UmVmKGRpZEFsdGVyKTtcbiAgICAgIChyZW1vdmVkIHx8ICFleGlzdHMpICYmIFNldFJlZihkaWRDaGFuZ2VTaXplKTtcblxuICAgICAgaWYgKHJlbW92ZWQgJiYgZW50cmllcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgcmV0dXJuOyAvLyB1bmRlZmluZWRcbiAgICAgIH1cblxuICAgICAgaWYgKCFleGlzdHMgJiYgIXJlbW92ZWQgJiYgZW50cmllcy5sZW5ndGggPj0gTUFYX0FSUkFZX01BUF9TSVpFKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVOb2Rlcyhvd25lcklELCBlbnRyaWVzLCBrZXksIHZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGlzRWRpdGFibGUgPSBvd25lcklEICYmIG93bmVySUQgPT09IHRoaXMub3duZXJJRDtcbiAgICAgIHZhciBuZXdFbnRyaWVzID0gaXNFZGl0YWJsZSA/IGVudHJpZXMgOiBhcnJDb3B5KGVudHJpZXMpO1xuXG4gICAgICBpZiAoZXhpc3RzKSB7XG4gICAgICAgIGlmIChyZW1vdmVkKSB7XG4gICAgICAgICAgaWR4ID09PSBsZW4gLSAxID8gbmV3RW50cmllcy5wb3AoKSA6IChuZXdFbnRyaWVzW2lkeF0gPSBuZXdFbnRyaWVzLnBvcCgpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdFbnRyaWVzW2lkeF0gPSBba2V5LCB2YWx1ZV07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5ld0VudHJpZXMucHVzaChba2V5LCB2YWx1ZV0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNFZGl0YWJsZSkge1xuICAgICAgICB0aGlzLmVudHJpZXMgPSBuZXdFbnRyaWVzO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5ldyBBcnJheU1hcE5vZGUob3duZXJJRCwgbmV3RW50cmllcyk7XG4gICAgfTtcblxuXG5cblxuICAgIGZ1bmN0aW9uIEJpdG1hcEluZGV4ZWROb2RlKG93bmVySUQsIGJpdG1hcCwgbm9kZXMpIHtcbiAgICAgIHRoaXMub3duZXJJRCA9IG93bmVySUQ7XG4gICAgICB0aGlzLmJpdG1hcCA9IGJpdG1hcDtcbiAgICAgIHRoaXMubm9kZXMgPSBub2RlcztcbiAgICB9XG5cbiAgICBCaXRtYXBJbmRleGVkTm9kZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oc2hpZnQsIGtleUhhc2gsIGtleSwgbm90U2V0VmFsdWUpIHtcbiAgICAgIGlmIChrZXlIYXNoID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAga2V5SGFzaCA9IGhhc2goa2V5KTtcbiAgICAgIH1cbiAgICAgIHZhciBiaXQgPSAoMSA8PCAoKHNoaWZ0ID09PSAwID8ga2V5SGFzaCA6IGtleUhhc2ggPj4+IHNoaWZ0KSAmIE1BU0spKTtcbiAgICAgIHZhciBiaXRtYXAgPSB0aGlzLmJpdG1hcDtcbiAgICAgIHJldHVybiAoYml0bWFwICYgYml0KSA9PT0gMCA/IG5vdFNldFZhbHVlIDpcbiAgICAgICAgdGhpcy5ub2Rlc1twb3BDb3VudChiaXRtYXAgJiAoYml0IC0gMSkpXS5nZXQoc2hpZnQgKyBTSElGVCwga2V5SGFzaCwga2V5LCBub3RTZXRWYWx1ZSk7XG4gICAgfTtcblxuICAgIEJpdG1hcEluZGV4ZWROb2RlLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbihvd25lcklELCBzaGlmdCwga2V5SGFzaCwga2V5LCB2YWx1ZSwgZGlkQ2hhbmdlU2l6ZSwgZGlkQWx0ZXIpIHtcbiAgICAgIGlmIChrZXlIYXNoID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAga2V5SGFzaCA9IGhhc2goa2V5KTtcbiAgICAgIH1cbiAgICAgIHZhciBrZXlIYXNoRnJhZyA9IChzaGlmdCA9PT0gMCA/IGtleUhhc2ggOiBrZXlIYXNoID4+PiBzaGlmdCkgJiBNQVNLO1xuICAgICAgdmFyIGJpdCA9IDEgPDwga2V5SGFzaEZyYWc7XG4gICAgICB2YXIgYml0bWFwID0gdGhpcy5iaXRtYXA7XG4gICAgICB2YXIgZXhpc3RzID0gKGJpdG1hcCAmIGJpdCkgIT09IDA7XG5cbiAgICAgIGlmICghZXhpc3RzICYmIHZhbHVlID09PSBOT1RfU0VUKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICB2YXIgaWR4ID0gcG9wQ291bnQoYml0bWFwICYgKGJpdCAtIDEpKTtcbiAgICAgIHZhciBub2RlcyA9IHRoaXMubm9kZXM7XG4gICAgICB2YXIgbm9kZSA9IGV4aXN0cyA/IG5vZGVzW2lkeF0gOiB1bmRlZmluZWQ7XG4gICAgICB2YXIgbmV3Tm9kZSA9IHVwZGF0ZU5vZGUobm9kZSwgb3duZXJJRCwgc2hpZnQgKyBTSElGVCwga2V5SGFzaCwga2V5LCB2YWx1ZSwgZGlkQ2hhbmdlU2l6ZSwgZGlkQWx0ZXIpO1xuXG4gICAgICBpZiAobmV3Tm9kZSA9PT0gbm9kZSkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgaWYgKCFleGlzdHMgJiYgbmV3Tm9kZSAmJiBub2Rlcy5sZW5ndGggPj0gTUFYX0JJVE1BUF9JTkRFWEVEX1NJWkUpIHtcbiAgICAgICAgcmV0dXJuIGV4cGFuZE5vZGVzKG93bmVySUQsIG5vZGVzLCBiaXRtYXAsIGtleUhhc2hGcmFnLCBuZXdOb2RlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGV4aXN0cyAmJiAhbmV3Tm9kZSAmJiBub2Rlcy5sZW5ndGggPT09IDIgJiYgaXNMZWFmTm9kZShub2Rlc1tpZHggXiAxXSkpIHtcbiAgICAgICAgcmV0dXJuIG5vZGVzW2lkeCBeIDFdO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXhpc3RzICYmIG5ld05vZGUgJiYgbm9kZXMubGVuZ3RoID09PSAxICYmIGlzTGVhZk5vZGUobmV3Tm9kZSkpIHtcbiAgICAgICAgcmV0dXJuIG5ld05vZGU7XG4gICAgICB9XG5cbiAgICAgIHZhciBpc0VkaXRhYmxlID0gb3duZXJJRCAmJiBvd25lcklEID09PSB0aGlzLm93bmVySUQ7XG4gICAgICB2YXIgbmV3Qml0bWFwID0gZXhpc3RzID8gbmV3Tm9kZSA/IGJpdG1hcCA6IGJpdG1hcCBeIGJpdCA6IGJpdG1hcCB8IGJpdDtcbiAgICAgIHZhciBuZXdOb2RlcyA9IGV4aXN0cyA/IG5ld05vZGUgP1xuICAgICAgICBzZXRJbihub2RlcywgaWR4LCBuZXdOb2RlLCBpc0VkaXRhYmxlKSA6XG4gICAgICAgIHNwbGljZU91dChub2RlcywgaWR4LCBpc0VkaXRhYmxlKSA6XG4gICAgICAgIHNwbGljZUluKG5vZGVzLCBpZHgsIG5ld05vZGUsIGlzRWRpdGFibGUpO1xuXG4gICAgICBpZiAoaXNFZGl0YWJsZSkge1xuICAgICAgICB0aGlzLmJpdG1hcCA9IG5ld0JpdG1hcDtcbiAgICAgICAgdGhpcy5ub2RlcyA9IG5ld05vZGVzO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5ldyBCaXRtYXBJbmRleGVkTm9kZShvd25lcklELCBuZXdCaXRtYXAsIG5ld05vZGVzKTtcbiAgICB9O1xuXG5cblxuXG4gICAgZnVuY3Rpb24gSGFzaEFycmF5TWFwTm9kZShvd25lcklELCBjb3VudCwgbm9kZXMpIHtcbiAgICAgIHRoaXMub3duZXJJRCA9IG93bmVySUQ7XG4gICAgICB0aGlzLmNvdW50ID0gY291bnQ7XG4gICAgICB0aGlzLm5vZGVzID0gbm9kZXM7XG4gICAgfVxuXG4gICAgSGFzaEFycmF5TWFwTm9kZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oc2hpZnQsIGtleUhhc2gsIGtleSwgbm90U2V0VmFsdWUpIHtcbiAgICAgIGlmIChrZXlIYXNoID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAga2V5SGFzaCA9IGhhc2goa2V5KTtcbiAgICAgIH1cbiAgICAgIHZhciBpZHggPSAoc2hpZnQgPT09IDAgPyBrZXlIYXNoIDoga2V5SGFzaCA+Pj4gc2hpZnQpICYgTUFTSztcbiAgICAgIHZhciBub2RlID0gdGhpcy5ub2Rlc1tpZHhdO1xuICAgICAgcmV0dXJuIG5vZGUgPyBub2RlLmdldChzaGlmdCArIFNISUZULCBrZXlIYXNoLCBrZXksIG5vdFNldFZhbHVlKSA6IG5vdFNldFZhbHVlO1xuICAgIH07XG5cbiAgICBIYXNoQXJyYXlNYXBOb2RlLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbihvd25lcklELCBzaGlmdCwga2V5SGFzaCwga2V5LCB2YWx1ZSwgZGlkQ2hhbmdlU2l6ZSwgZGlkQWx0ZXIpIHtcbiAgICAgIGlmIChrZXlIYXNoID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAga2V5SGFzaCA9IGhhc2goa2V5KTtcbiAgICAgIH1cbiAgICAgIHZhciBpZHggPSAoc2hpZnQgPT09IDAgPyBrZXlIYXNoIDoga2V5SGFzaCA+Pj4gc2hpZnQpICYgTUFTSztcbiAgICAgIHZhciByZW1vdmVkID0gdmFsdWUgPT09IE5PVF9TRVQ7XG4gICAgICB2YXIgbm9kZXMgPSB0aGlzLm5vZGVzO1xuICAgICAgdmFyIG5vZGUgPSBub2Rlc1tpZHhdO1xuXG4gICAgICBpZiAocmVtb3ZlZCAmJiAhbm9kZSkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgdmFyIG5ld05vZGUgPSB1cGRhdGVOb2RlKG5vZGUsIG93bmVySUQsIHNoaWZ0ICsgU0hJRlQsIGtleUhhc2gsIGtleSwgdmFsdWUsIGRpZENoYW5nZVNpemUsIGRpZEFsdGVyKTtcbiAgICAgIGlmIChuZXdOb2RlID09PSBub2RlKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICB2YXIgbmV3Q291bnQgPSB0aGlzLmNvdW50O1xuICAgICAgaWYgKCFub2RlKSB7XG4gICAgICAgIG5ld0NvdW50Kys7XG4gICAgICB9IGVsc2UgaWYgKCFuZXdOb2RlKSB7XG4gICAgICAgIG5ld0NvdW50LS07XG4gICAgICAgIGlmIChuZXdDb3VudCA8IE1JTl9IQVNIX0FSUkFZX01BUF9TSVpFKSB7XG4gICAgICAgICAgcmV0dXJuIHBhY2tOb2Rlcyhvd25lcklELCBub2RlcywgbmV3Q291bnQsIGlkeCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIGlzRWRpdGFibGUgPSBvd25lcklEICYmIG93bmVySUQgPT09IHRoaXMub3duZXJJRDtcbiAgICAgIHZhciBuZXdOb2RlcyA9IHNldEluKG5vZGVzLCBpZHgsIG5ld05vZGUsIGlzRWRpdGFibGUpO1xuXG4gICAgICBpZiAoaXNFZGl0YWJsZSkge1xuICAgICAgICB0aGlzLmNvdW50ID0gbmV3Q291bnQ7XG4gICAgICAgIHRoaXMubm9kZXMgPSBuZXdOb2RlcztcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuZXcgSGFzaEFycmF5TWFwTm9kZShvd25lcklELCBuZXdDb3VudCwgbmV3Tm9kZXMpO1xuICAgIH07XG5cblxuXG5cbiAgICBmdW5jdGlvbiBIYXNoQ29sbGlzaW9uTm9kZShvd25lcklELCBrZXlIYXNoLCBlbnRyaWVzKSB7XG4gICAgICB0aGlzLm93bmVySUQgPSBvd25lcklEO1xuICAgICAgdGhpcy5rZXlIYXNoID0ga2V5SGFzaDtcbiAgICAgIHRoaXMuZW50cmllcyA9IGVudHJpZXM7XG4gICAgfVxuXG4gICAgSGFzaENvbGxpc2lvbk5vZGUucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKHNoaWZ0LCBrZXlIYXNoLCBrZXksIG5vdFNldFZhbHVlKSB7XG4gICAgICB2YXIgZW50cmllcyA9IHRoaXMuZW50cmllcztcbiAgICAgIGZvciAodmFyIGlpID0gMCwgbGVuID0gZW50cmllcy5sZW5ndGg7IGlpIDwgbGVuOyBpaSsrKSB7XG4gICAgICAgIGlmIChpcyhrZXksIGVudHJpZXNbaWldWzBdKSkge1xuICAgICAgICAgIHJldHVybiBlbnRyaWVzW2lpXVsxXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG5vdFNldFZhbHVlO1xuICAgIH07XG5cbiAgICBIYXNoQ29sbGlzaW9uTm9kZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24ob3duZXJJRCwgc2hpZnQsIGtleUhhc2gsIGtleSwgdmFsdWUsIGRpZENoYW5nZVNpemUsIGRpZEFsdGVyKSB7XG4gICAgICBpZiAoa2V5SGFzaCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGtleUhhc2ggPSBoYXNoKGtleSk7XG4gICAgICB9XG5cbiAgICAgIHZhciByZW1vdmVkID0gdmFsdWUgPT09IE5PVF9TRVQ7XG5cbiAgICAgIGlmIChrZXlIYXNoICE9PSB0aGlzLmtleUhhc2gpIHtcbiAgICAgICAgaWYgKHJlbW92ZWQpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICBTZXRSZWYoZGlkQWx0ZXIpO1xuICAgICAgICBTZXRSZWYoZGlkQ2hhbmdlU2l6ZSk7XG4gICAgICAgIHJldHVybiBtZXJnZUludG9Ob2RlKHRoaXMsIG93bmVySUQsIHNoaWZ0LCBrZXlIYXNoLCBba2V5LCB2YWx1ZV0pO1xuICAgICAgfVxuXG4gICAgICB2YXIgZW50cmllcyA9IHRoaXMuZW50cmllcztcbiAgICAgIHZhciBpZHggPSAwO1xuICAgICAgZm9yICh2YXIgbGVuID0gZW50cmllcy5sZW5ndGg7IGlkeCA8IGxlbjsgaWR4KyspIHtcbiAgICAgICAgaWYgKGlzKGtleSwgZW50cmllc1tpZHhdWzBdKSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB2YXIgZXhpc3RzID0gaWR4IDwgbGVuO1xuXG4gICAgICBpZiAoZXhpc3RzID8gZW50cmllc1tpZHhdWzFdID09PSB2YWx1ZSA6IHJlbW92ZWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIFNldFJlZihkaWRBbHRlcik7XG4gICAgICAocmVtb3ZlZCB8fCAhZXhpc3RzKSAmJiBTZXRSZWYoZGlkQ2hhbmdlU2l6ZSk7XG5cbiAgICAgIGlmIChyZW1vdmVkICYmIGxlbiA9PT0gMikge1xuICAgICAgICByZXR1cm4gbmV3IFZhbHVlTm9kZShvd25lcklELCB0aGlzLmtleUhhc2gsIGVudHJpZXNbaWR4IF4gMV0pO1xuICAgICAgfVxuXG4gICAgICB2YXIgaXNFZGl0YWJsZSA9IG93bmVySUQgJiYgb3duZXJJRCA9PT0gdGhpcy5vd25lcklEO1xuICAgICAgdmFyIG5ld0VudHJpZXMgPSBpc0VkaXRhYmxlID8gZW50cmllcyA6IGFyckNvcHkoZW50cmllcyk7XG5cbiAgICAgIGlmIChleGlzdHMpIHtcbiAgICAgICAgaWYgKHJlbW92ZWQpIHtcbiAgICAgICAgICBpZHggPT09IGxlbiAtIDEgPyBuZXdFbnRyaWVzLnBvcCgpIDogKG5ld0VudHJpZXNbaWR4XSA9IG5ld0VudHJpZXMucG9wKCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5ld0VudHJpZXNbaWR4XSA9IFtrZXksIHZhbHVlXTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV3RW50cmllcy5wdXNoKFtrZXksIHZhbHVlXSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0VkaXRhYmxlKSB7XG4gICAgICAgIHRoaXMuZW50cmllcyA9IG5ld0VudHJpZXM7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmV3IEhhc2hDb2xsaXNpb25Ob2RlKG93bmVySUQsIHRoaXMua2V5SGFzaCwgbmV3RW50cmllcyk7XG4gICAgfTtcblxuXG5cblxuICAgIGZ1bmN0aW9uIFZhbHVlTm9kZShvd25lcklELCBrZXlIYXNoLCBlbnRyeSkge1xuICAgICAgdGhpcy5vd25lcklEID0gb3duZXJJRDtcbiAgICAgIHRoaXMua2V5SGFzaCA9IGtleUhhc2g7XG4gICAgICB0aGlzLmVudHJ5ID0gZW50cnk7XG4gICAgfVxuXG4gICAgVmFsdWVOb2RlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihzaGlmdCwga2V5SGFzaCwga2V5LCBub3RTZXRWYWx1ZSkge1xuICAgICAgcmV0dXJuIGlzKGtleSwgdGhpcy5lbnRyeVswXSkgPyB0aGlzLmVudHJ5WzFdIDogbm90U2V0VmFsdWU7XG4gICAgfTtcblxuICAgIFZhbHVlTm9kZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24ob3duZXJJRCwgc2hpZnQsIGtleUhhc2gsIGtleSwgdmFsdWUsIGRpZENoYW5nZVNpemUsIGRpZEFsdGVyKSB7XG4gICAgICB2YXIgcmVtb3ZlZCA9IHZhbHVlID09PSBOT1RfU0VUO1xuICAgICAgdmFyIGtleU1hdGNoID0gaXMoa2V5LCB0aGlzLmVudHJ5WzBdKTtcbiAgICAgIGlmIChrZXlNYXRjaCA/IHZhbHVlID09PSB0aGlzLmVudHJ5WzFdIDogcmVtb3ZlZCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgU2V0UmVmKGRpZEFsdGVyKTtcblxuICAgICAgaWYgKHJlbW92ZWQpIHtcbiAgICAgICAgU2V0UmVmKGRpZENoYW5nZVNpemUpO1xuICAgICAgICByZXR1cm47IC8vIHVuZGVmaW5lZFxuICAgICAgfVxuXG4gICAgICBpZiAoa2V5TWF0Y2gpIHtcbiAgICAgICAgaWYgKG93bmVySUQgJiYgb3duZXJJRCA9PT0gdGhpcy5vd25lcklEKSB7XG4gICAgICAgICAgdGhpcy5lbnRyeVsxXSA9IHZhbHVlO1xuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgVmFsdWVOb2RlKG93bmVySUQsIHRoaXMua2V5SGFzaCwgW2tleSwgdmFsdWVdKTtcbiAgICAgIH1cblxuICAgICAgU2V0UmVmKGRpZENoYW5nZVNpemUpO1xuICAgICAgcmV0dXJuIG1lcmdlSW50b05vZGUodGhpcywgb3duZXJJRCwgc2hpZnQsIGhhc2goa2V5KSwgW2tleSwgdmFsdWVdKTtcbiAgICB9O1xuXG5cblxuICAvLyAjcHJhZ21hIEl0ZXJhdG9yc1xuXG4gIEFycmF5TWFwTm9kZS5wcm90b3R5cGUuaXRlcmF0ZSA9XG4gIEhhc2hDb2xsaXNpb25Ob2RlLnByb3RvdHlwZS5pdGVyYXRlID0gZnVuY3Rpb24gKGZuLCByZXZlcnNlKSB7XG4gICAgdmFyIGVudHJpZXMgPSB0aGlzLmVudHJpZXM7XG4gICAgZm9yICh2YXIgaWkgPSAwLCBtYXhJbmRleCA9IGVudHJpZXMubGVuZ3RoIC0gMTsgaWkgPD0gbWF4SW5kZXg7IGlpKyspIHtcbiAgICAgIGlmIChmbihlbnRyaWVzW3JldmVyc2UgPyBtYXhJbmRleCAtIGlpIDogaWldKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIEJpdG1hcEluZGV4ZWROb2RlLnByb3RvdHlwZS5pdGVyYXRlID1cbiAgSGFzaEFycmF5TWFwTm9kZS5wcm90b3R5cGUuaXRlcmF0ZSA9IGZ1bmN0aW9uIChmbiwgcmV2ZXJzZSkge1xuICAgIHZhciBub2RlcyA9IHRoaXMubm9kZXM7XG4gICAgZm9yICh2YXIgaWkgPSAwLCBtYXhJbmRleCA9IG5vZGVzLmxlbmd0aCAtIDE7IGlpIDw9IG1heEluZGV4OyBpaSsrKSB7XG4gICAgICB2YXIgbm9kZSA9IG5vZGVzW3JldmVyc2UgPyBtYXhJbmRleCAtIGlpIDogaWldO1xuICAgICAgaWYgKG5vZGUgJiYgbm9kZS5pdGVyYXRlKGZuLCByZXZlcnNlKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIFZhbHVlTm9kZS5wcm90b3R5cGUuaXRlcmF0ZSA9IGZ1bmN0aW9uIChmbiwgcmV2ZXJzZSkge1xuICAgIHJldHVybiBmbih0aGlzLmVudHJ5KTtcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKE1hcEl0ZXJhdG9yLCBJdGVyYXRvcik7XG5cbiAgICBmdW5jdGlvbiBNYXBJdGVyYXRvcihtYXAsIHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgdGhpcy5fcmV2ZXJzZSA9IHJldmVyc2U7XG4gICAgICB0aGlzLl9zdGFjayA9IG1hcC5fcm9vdCAmJiBtYXBJdGVyYXRvckZyYW1lKG1hcC5fcm9vdCk7XG4gICAgfVxuXG4gICAgTWFwSXRlcmF0b3IucHJvdG90eXBlLm5leHQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciB0eXBlID0gdGhpcy5fdHlwZTtcbiAgICAgIHZhciBzdGFjayA9IHRoaXMuX3N0YWNrO1xuICAgICAgd2hpbGUgKHN0YWNrKSB7XG4gICAgICAgIHZhciBub2RlID0gc3RhY2subm9kZTtcbiAgICAgICAgdmFyIGluZGV4ID0gc3RhY2suaW5kZXgrKztcbiAgICAgICAgdmFyIG1heEluZGV4O1xuICAgICAgICBpZiAobm9kZS5lbnRyeSkge1xuICAgICAgICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIG1hcEl0ZXJhdG9yVmFsdWUodHlwZSwgbm9kZS5lbnRyeSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKG5vZGUuZW50cmllcykge1xuICAgICAgICAgIG1heEluZGV4ID0gbm9kZS5lbnRyaWVzLmxlbmd0aCAtIDE7XG4gICAgICAgICAgaWYgKGluZGV4IDw9IG1heEluZGV4KSB7XG4gICAgICAgICAgICByZXR1cm4gbWFwSXRlcmF0b3JWYWx1ZSh0eXBlLCBub2RlLmVudHJpZXNbdGhpcy5fcmV2ZXJzZSA/IG1heEluZGV4IC0gaW5kZXggOiBpbmRleF0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtYXhJbmRleCA9IG5vZGUubm9kZXMubGVuZ3RoIC0gMTtcbiAgICAgICAgICBpZiAoaW5kZXggPD0gbWF4SW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBzdWJOb2RlID0gbm9kZS5ub2Rlc1t0aGlzLl9yZXZlcnNlID8gbWF4SW5kZXggLSBpbmRleCA6IGluZGV4XTtcbiAgICAgICAgICAgIGlmIChzdWJOb2RlKSB7XG4gICAgICAgICAgICAgIGlmIChzdWJOb2RlLmVudHJ5KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hcEl0ZXJhdG9yVmFsdWUodHlwZSwgc3ViTm9kZS5lbnRyeSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgc3RhY2sgPSB0aGlzLl9zdGFjayA9IG1hcEl0ZXJhdG9yRnJhbWUoc3ViTm9kZSwgc3RhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN0YWNrID0gdGhpcy5fc3RhY2sgPSB0aGlzLl9zdGFjay5fX3ByZXY7XG4gICAgICB9XG4gICAgICByZXR1cm4gaXRlcmF0b3JEb25lKCk7XG4gICAgfTtcblxuXG4gIGZ1bmN0aW9uIG1hcEl0ZXJhdG9yVmFsdWUodHlwZSwgZW50cnkpIHtcbiAgICByZXR1cm4gaXRlcmF0b3JWYWx1ZSh0eXBlLCBlbnRyeVswXSwgZW50cnlbMV0pO1xuICB9XG5cbiAgZnVuY3Rpb24gbWFwSXRlcmF0b3JGcmFtZShub2RlLCBwcmV2KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5vZGU6IG5vZGUsXG4gICAgICBpbmRleDogMCxcbiAgICAgIF9fcHJldjogcHJldlxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBtYWtlTWFwKHNpemUsIHJvb3QsIG93bmVySUQsIGhhc2gpIHtcbiAgICB2YXIgbWFwID0gT2JqZWN0LmNyZWF0ZShNYXBQcm90b3R5cGUpO1xuICAgIG1hcC5zaXplID0gc2l6ZTtcbiAgICBtYXAuX3Jvb3QgPSByb290O1xuICAgIG1hcC5fX293bmVySUQgPSBvd25lcklEO1xuICAgIG1hcC5fX2hhc2ggPSBoYXNoO1xuICAgIG1hcC5fX2FsdGVyZWQgPSBmYWxzZTtcbiAgICByZXR1cm4gbWFwO1xuICB9XG5cbiAgdmFyIEVNUFRZX01BUDtcbiAgZnVuY3Rpb24gZW1wdHlNYXAoKSB7XG4gICAgcmV0dXJuIEVNUFRZX01BUCB8fCAoRU1QVFlfTUFQID0gbWFrZU1hcCgwKSk7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVNYXAobWFwLCBrLCB2KSB7XG4gICAgdmFyIG5ld1Jvb3Q7XG4gICAgdmFyIG5ld1NpemU7XG4gICAgaWYgKCFtYXAuX3Jvb3QpIHtcbiAgICAgIGlmICh2ID09PSBOT1RfU0VUKSB7XG4gICAgICAgIHJldHVybiBtYXA7XG4gICAgICB9XG4gICAgICBuZXdTaXplID0gMTtcbiAgICAgIG5ld1Jvb3QgPSBuZXcgQXJyYXlNYXBOb2RlKG1hcC5fX293bmVySUQsIFtbaywgdl1dKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGRpZENoYW5nZVNpemUgPSBNYWtlUmVmKENIQU5HRV9MRU5HVEgpO1xuICAgICAgdmFyIGRpZEFsdGVyID0gTWFrZVJlZihESURfQUxURVIpO1xuICAgICAgbmV3Um9vdCA9IHVwZGF0ZU5vZGUobWFwLl9yb290LCBtYXAuX19vd25lcklELCAwLCB1bmRlZmluZWQsIGssIHYsIGRpZENoYW5nZVNpemUsIGRpZEFsdGVyKTtcbiAgICAgIGlmICghZGlkQWx0ZXIudmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIG1hcDtcbiAgICAgIH1cbiAgICAgIG5ld1NpemUgPSBtYXAuc2l6ZSArIChkaWRDaGFuZ2VTaXplLnZhbHVlID8gdiA9PT0gTk9UX1NFVCA/IC0xIDogMSA6IDApO1xuICAgIH1cbiAgICBpZiAobWFwLl9fb3duZXJJRCkge1xuICAgICAgbWFwLnNpemUgPSBuZXdTaXplO1xuICAgICAgbWFwLl9yb290ID0gbmV3Um9vdDtcbiAgICAgIG1hcC5fX2hhc2ggPSB1bmRlZmluZWQ7XG4gICAgICBtYXAuX19hbHRlcmVkID0gdHJ1ZTtcbiAgICAgIHJldHVybiBtYXA7XG4gICAgfVxuICAgIHJldHVybiBuZXdSb290ID8gbWFrZU1hcChuZXdTaXplLCBuZXdSb290KSA6IGVtcHR5TWFwKCk7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVOb2RlKG5vZGUsIG93bmVySUQsIHNoaWZ0LCBrZXlIYXNoLCBrZXksIHZhbHVlLCBkaWRDaGFuZ2VTaXplLCBkaWRBbHRlcikge1xuICAgIGlmICghbm9kZSkge1xuICAgICAgaWYgKHZhbHVlID09PSBOT1RfU0VUKSB7XG4gICAgICAgIHJldHVybiBub2RlO1xuICAgICAgfVxuICAgICAgU2V0UmVmKGRpZEFsdGVyKTtcbiAgICAgIFNldFJlZihkaWRDaGFuZ2VTaXplKTtcbiAgICAgIHJldHVybiBuZXcgVmFsdWVOb2RlKG93bmVySUQsIGtleUhhc2gsIFtrZXksIHZhbHVlXSk7XG4gICAgfVxuICAgIHJldHVybiBub2RlLnVwZGF0ZShvd25lcklELCBzaGlmdCwga2V5SGFzaCwga2V5LCB2YWx1ZSwgZGlkQ2hhbmdlU2l6ZSwgZGlkQWx0ZXIpO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNMZWFmTm9kZShub2RlKSB7XG4gICAgcmV0dXJuIG5vZGUuY29uc3RydWN0b3IgPT09IFZhbHVlTm9kZSB8fCBub2RlLmNvbnN0cnVjdG9yID09PSBIYXNoQ29sbGlzaW9uTm9kZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1lcmdlSW50b05vZGUobm9kZSwgb3duZXJJRCwgc2hpZnQsIGtleUhhc2gsIGVudHJ5KSB7XG4gICAgaWYgKG5vZGUua2V5SGFzaCA9PT0ga2V5SGFzaCkge1xuICAgICAgcmV0dXJuIG5ldyBIYXNoQ29sbGlzaW9uTm9kZShvd25lcklELCBrZXlIYXNoLCBbbm9kZS5lbnRyeSwgZW50cnldKTtcbiAgICB9XG5cbiAgICB2YXIgaWR4MSA9IChzaGlmdCA9PT0gMCA/IG5vZGUua2V5SGFzaCA6IG5vZGUua2V5SGFzaCA+Pj4gc2hpZnQpICYgTUFTSztcbiAgICB2YXIgaWR4MiA9IChzaGlmdCA9PT0gMCA/IGtleUhhc2ggOiBrZXlIYXNoID4+PiBzaGlmdCkgJiBNQVNLO1xuXG4gICAgdmFyIG5ld05vZGU7XG4gICAgdmFyIG5vZGVzID0gaWR4MSA9PT0gaWR4MiA/XG4gICAgICBbbWVyZ2VJbnRvTm9kZShub2RlLCBvd25lcklELCBzaGlmdCArIFNISUZULCBrZXlIYXNoLCBlbnRyeSldIDpcbiAgICAgICgobmV3Tm9kZSA9IG5ldyBWYWx1ZU5vZGUob3duZXJJRCwga2V5SGFzaCwgZW50cnkpKSwgaWR4MSA8IGlkeDIgPyBbbm9kZSwgbmV3Tm9kZV0gOiBbbmV3Tm9kZSwgbm9kZV0pO1xuXG4gICAgcmV0dXJuIG5ldyBCaXRtYXBJbmRleGVkTm9kZShvd25lcklELCAoMSA8PCBpZHgxKSB8ICgxIDw8IGlkeDIpLCBub2Rlcyk7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVOb2Rlcyhvd25lcklELCBlbnRyaWVzLCBrZXksIHZhbHVlKSB7XG4gICAgaWYgKCFvd25lcklEKSB7XG4gICAgICBvd25lcklEID0gbmV3IE93bmVySUQoKTtcbiAgICB9XG4gICAgdmFyIG5vZGUgPSBuZXcgVmFsdWVOb2RlKG93bmVySUQsIGhhc2goa2V5KSwgW2tleSwgdmFsdWVdKTtcbiAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgZW50cmllcy5sZW5ndGg7IGlpKyspIHtcbiAgICAgIHZhciBlbnRyeSA9IGVudHJpZXNbaWldO1xuICAgICAgbm9kZSA9IG5vZGUudXBkYXRlKG93bmVySUQsIDAsIHVuZGVmaW5lZCwgZW50cnlbMF0sIGVudHJ5WzFdKTtcbiAgICB9XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cblxuICBmdW5jdGlvbiBwYWNrTm9kZXMob3duZXJJRCwgbm9kZXMsIGNvdW50LCBleGNsdWRpbmcpIHtcbiAgICB2YXIgYml0bWFwID0gMDtcbiAgICB2YXIgcGFja2VkSUkgPSAwO1xuICAgIHZhciBwYWNrZWROb2RlcyA9IG5ldyBBcnJheShjb3VudCk7XG4gICAgZm9yICh2YXIgaWkgPSAwLCBiaXQgPSAxLCBsZW4gPSBub2Rlcy5sZW5ndGg7IGlpIDwgbGVuOyBpaSsrLCBiaXQgPDw9IDEpIHtcbiAgICAgIHZhciBub2RlID0gbm9kZXNbaWldO1xuICAgICAgaWYgKG5vZGUgIT09IHVuZGVmaW5lZCAmJiBpaSAhPT0gZXhjbHVkaW5nKSB7XG4gICAgICAgIGJpdG1hcCB8PSBiaXQ7XG4gICAgICAgIHBhY2tlZE5vZGVzW3BhY2tlZElJKytdID0gbm9kZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ldyBCaXRtYXBJbmRleGVkTm9kZShvd25lcklELCBiaXRtYXAsIHBhY2tlZE5vZGVzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGV4cGFuZE5vZGVzKG93bmVySUQsIG5vZGVzLCBiaXRtYXAsIGluY2x1ZGluZywgbm9kZSkge1xuICAgIHZhciBjb3VudCA9IDA7XG4gICAgdmFyIGV4cGFuZGVkTm9kZXMgPSBuZXcgQXJyYXkoU0laRSk7XG4gICAgZm9yICh2YXIgaWkgPSAwOyBiaXRtYXAgIT09IDA7IGlpKyssIGJpdG1hcCA+Pj49IDEpIHtcbiAgICAgIGV4cGFuZGVkTm9kZXNbaWldID0gYml0bWFwICYgMSA/IG5vZGVzW2NvdW50KytdIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgICBleHBhbmRlZE5vZGVzW2luY2x1ZGluZ10gPSBub2RlO1xuICAgIHJldHVybiBuZXcgSGFzaEFycmF5TWFwTm9kZShvd25lcklELCBjb3VudCArIDEsIGV4cGFuZGVkTm9kZXMpO1xuICB9XG5cbiAgZnVuY3Rpb24gbWVyZ2VJbnRvTWFwV2l0aChtYXAsIG1lcmdlciwgaXRlcmFibGVzKSB7XG4gICAgdmFyIGl0ZXJzID0gW107XG4gICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IGl0ZXJhYmxlcy5sZW5ndGg7IGlpKyspIHtcbiAgICAgIHZhciB2YWx1ZSA9IGl0ZXJhYmxlc1tpaV07XG4gICAgICB2YXIgaXRlciA9IEtleWVkSXRlcmFibGUodmFsdWUpO1xuICAgICAgaWYgKCFpc0l0ZXJhYmxlKHZhbHVlKSkge1xuICAgICAgICBpdGVyID0gaXRlci5tYXAoZnVuY3Rpb24odiApIHtyZXR1cm4gZnJvbUpTKHYpfSk7XG4gICAgICB9XG4gICAgICBpdGVycy5wdXNoKGl0ZXIpO1xuICAgIH1cbiAgICByZXR1cm4gbWVyZ2VJbnRvQ29sbGVjdGlvbldpdGgobWFwLCBtZXJnZXIsIGl0ZXJzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlZXBNZXJnZXIoZXhpc3RpbmcsIHZhbHVlLCBrZXkpIHtcbiAgICByZXR1cm4gZXhpc3RpbmcgJiYgZXhpc3RpbmcubWVyZ2VEZWVwICYmIGlzSXRlcmFibGUodmFsdWUpID9cbiAgICAgIGV4aXN0aW5nLm1lcmdlRGVlcCh2YWx1ZSkgOlxuICAgICAgaXMoZXhpc3RpbmcsIHZhbHVlKSA/IGV4aXN0aW5nIDogdmFsdWU7XG4gIH1cblxuICBmdW5jdGlvbiBkZWVwTWVyZ2VyV2l0aChtZXJnZXIpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oZXhpc3RpbmcsIHZhbHVlLCBrZXkpICB7XG4gICAgICBpZiAoZXhpc3RpbmcgJiYgZXhpc3RpbmcubWVyZ2VEZWVwV2l0aCAmJiBpc0l0ZXJhYmxlKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gZXhpc3RpbmcubWVyZ2VEZWVwV2l0aChtZXJnZXIsIHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHZhciBuZXh0VmFsdWUgPSBtZXJnZXIoZXhpc3RpbmcsIHZhbHVlLCBrZXkpO1xuICAgICAgcmV0dXJuIGlzKGV4aXN0aW5nLCBuZXh0VmFsdWUpID8gZXhpc3RpbmcgOiBuZXh0VmFsdWU7XG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1lcmdlSW50b0NvbGxlY3Rpb25XaXRoKGNvbGxlY3Rpb24sIG1lcmdlciwgaXRlcnMpIHtcbiAgICBpdGVycyA9IGl0ZXJzLmZpbHRlcihmdW5jdGlvbih4ICkge3JldHVybiB4LnNpemUgIT09IDB9KTtcbiAgICBpZiAoaXRlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gY29sbGVjdGlvbjtcbiAgICB9XG4gICAgaWYgKGNvbGxlY3Rpb24uc2l6ZSA9PT0gMCAmJiAhY29sbGVjdGlvbi5fX293bmVySUQgJiYgaXRlcnMubGVuZ3RoID09PSAxKSB7XG4gICAgICByZXR1cm4gY29sbGVjdGlvbi5jb25zdHJ1Y3RvcihpdGVyc1swXSk7XG4gICAgfVxuICAgIHJldHVybiBjb2xsZWN0aW9uLndpdGhNdXRhdGlvbnMoZnVuY3Rpb24oY29sbGVjdGlvbiApIHtcbiAgICAgIHZhciBtZXJnZUludG9NYXAgPSBtZXJnZXIgP1xuICAgICAgICBmdW5jdGlvbih2YWx1ZSwga2V5KSAge1xuICAgICAgICAgIGNvbGxlY3Rpb24udXBkYXRlKGtleSwgTk9UX1NFVCwgZnVuY3Rpb24oZXhpc3RpbmcgKVxuICAgICAgICAgICAge3JldHVybiBleGlzdGluZyA9PT0gTk9UX1NFVCA/IHZhbHVlIDogbWVyZ2VyKGV4aXN0aW5nLCB2YWx1ZSwga2V5KX1cbiAgICAgICAgICApO1xuICAgICAgICB9IDpcbiAgICAgICAgZnVuY3Rpb24odmFsdWUsIGtleSkgIHtcbiAgICAgICAgICBjb2xsZWN0aW9uLnNldChrZXksIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IGl0ZXJzLmxlbmd0aDsgaWkrKykge1xuICAgICAgICBpdGVyc1tpaV0uZm9yRWFjaChtZXJnZUludG9NYXApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlSW5EZWVwTWFwKGV4aXN0aW5nLCBrZXlQYXRoSXRlciwgbm90U2V0VmFsdWUsIHVwZGF0ZXIpIHtcbiAgICB2YXIgaXNOb3RTZXQgPSBleGlzdGluZyA9PT0gTk9UX1NFVDtcbiAgICB2YXIgc3RlcCA9IGtleVBhdGhJdGVyLm5leHQoKTtcbiAgICBpZiAoc3RlcC5kb25lKSB7XG4gICAgICB2YXIgZXhpc3RpbmdWYWx1ZSA9IGlzTm90U2V0ID8gbm90U2V0VmFsdWUgOiBleGlzdGluZztcbiAgICAgIHZhciBuZXdWYWx1ZSA9IHVwZGF0ZXIoZXhpc3RpbmdWYWx1ZSk7XG4gICAgICByZXR1cm4gbmV3VmFsdWUgPT09IGV4aXN0aW5nVmFsdWUgPyBleGlzdGluZyA6IG5ld1ZhbHVlO1xuICAgIH1cbiAgICBpbnZhcmlhbnQoXG4gICAgICBpc05vdFNldCB8fCAoZXhpc3RpbmcgJiYgZXhpc3Rpbmcuc2V0KSxcbiAgICAgICdpbnZhbGlkIGtleVBhdGgnXG4gICAgKTtcbiAgICB2YXIga2V5ID0gc3RlcC52YWx1ZTtcbiAgICB2YXIgbmV4dEV4aXN0aW5nID0gaXNOb3RTZXQgPyBOT1RfU0VUIDogZXhpc3RpbmcuZ2V0KGtleSwgTk9UX1NFVCk7XG4gICAgdmFyIG5leHRVcGRhdGVkID0gdXBkYXRlSW5EZWVwTWFwKFxuICAgICAgbmV4dEV4aXN0aW5nLFxuICAgICAga2V5UGF0aEl0ZXIsXG4gICAgICBub3RTZXRWYWx1ZSxcbiAgICAgIHVwZGF0ZXJcbiAgICApO1xuICAgIHJldHVybiBuZXh0VXBkYXRlZCA9PT0gbmV4dEV4aXN0aW5nID8gZXhpc3RpbmcgOlxuICAgICAgbmV4dFVwZGF0ZWQgPT09IE5PVF9TRVQgPyBleGlzdGluZy5yZW1vdmUoa2V5KSA6XG4gICAgICAoaXNOb3RTZXQgPyBlbXB0eU1hcCgpIDogZXhpc3RpbmcpLnNldChrZXksIG5leHRVcGRhdGVkKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBvcENvdW50KHgpIHtcbiAgICB4ID0geCAtICgoeCA+PiAxKSAmIDB4NTU1NTU1NTUpO1xuICAgIHggPSAoeCAmIDB4MzMzMzMzMzMpICsgKCh4ID4+IDIpICYgMHgzMzMzMzMzMyk7XG4gICAgeCA9ICh4ICsgKHggPj4gNCkpICYgMHgwZjBmMGYwZjtcbiAgICB4ID0geCArICh4ID4+IDgpO1xuICAgIHggPSB4ICsgKHggPj4gMTYpO1xuICAgIHJldHVybiB4ICYgMHg3ZjtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNldEluKGFycmF5LCBpZHgsIHZhbCwgY2FuRWRpdCkge1xuICAgIHZhciBuZXdBcnJheSA9IGNhbkVkaXQgPyBhcnJheSA6IGFyckNvcHkoYXJyYXkpO1xuICAgIG5ld0FycmF5W2lkeF0gPSB2YWw7XG4gICAgcmV0dXJuIG5ld0FycmF5O1xuICB9XG5cbiAgZnVuY3Rpb24gc3BsaWNlSW4oYXJyYXksIGlkeCwgdmFsLCBjYW5FZGl0KSB7XG4gICAgdmFyIG5ld0xlbiA9IGFycmF5Lmxlbmd0aCArIDE7XG4gICAgaWYgKGNhbkVkaXQgJiYgaWR4ICsgMSA9PT0gbmV3TGVuKSB7XG4gICAgICBhcnJheVtpZHhdID0gdmFsO1xuICAgICAgcmV0dXJuIGFycmF5O1xuICAgIH1cbiAgICB2YXIgbmV3QXJyYXkgPSBuZXcgQXJyYXkobmV3TGVuKTtcbiAgICB2YXIgYWZ0ZXIgPSAwO1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCBuZXdMZW47IGlpKyspIHtcbiAgICAgIGlmIChpaSA9PT0gaWR4KSB7XG4gICAgICAgIG5ld0FycmF5W2lpXSA9IHZhbDtcbiAgICAgICAgYWZ0ZXIgPSAtMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5ld0FycmF5W2lpXSA9IGFycmF5W2lpICsgYWZ0ZXJdO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbmV3QXJyYXk7XG4gIH1cblxuICBmdW5jdGlvbiBzcGxpY2VPdXQoYXJyYXksIGlkeCwgY2FuRWRpdCkge1xuICAgIHZhciBuZXdMZW4gPSBhcnJheS5sZW5ndGggLSAxO1xuICAgIGlmIChjYW5FZGl0ICYmIGlkeCA9PT0gbmV3TGVuKSB7XG4gICAgICBhcnJheS5wb3AoKTtcbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG4gICAgdmFyIG5ld0FycmF5ID0gbmV3IEFycmF5KG5ld0xlbik7XG4gICAgdmFyIGFmdGVyID0gMDtcbiAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgbmV3TGVuOyBpaSsrKSB7XG4gICAgICBpZiAoaWkgPT09IGlkeCkge1xuICAgICAgICBhZnRlciA9IDE7XG4gICAgICB9XG4gICAgICBuZXdBcnJheVtpaV0gPSBhcnJheVtpaSArIGFmdGVyXTtcbiAgICB9XG4gICAgcmV0dXJuIG5ld0FycmF5O1xuICB9XG5cbiAgdmFyIE1BWF9BUlJBWV9NQVBfU0laRSA9IFNJWkUgLyA0O1xuICB2YXIgTUFYX0JJVE1BUF9JTkRFWEVEX1NJWkUgPSBTSVpFIC8gMjtcbiAgdmFyIE1JTl9IQVNIX0FSUkFZX01BUF9TSVpFID0gU0laRSAvIDQ7XG5cbiAgY3JlYXRlQ2xhc3MoTGlzdCwgSW5kZXhlZENvbGxlY3Rpb24pO1xuXG4gICAgLy8gQHByYWdtYSBDb25zdHJ1Y3Rpb25cblxuICAgIGZ1bmN0aW9uIExpc3QodmFsdWUpIHtcbiAgICAgIHZhciBlbXB0eSA9IGVtcHR5TGlzdCgpO1xuICAgICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGVtcHR5O1xuICAgICAgfVxuICAgICAgaWYgKGlzTGlzdCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgdmFyIGl0ZXIgPSBJbmRleGVkSXRlcmFibGUodmFsdWUpO1xuICAgICAgdmFyIHNpemUgPSBpdGVyLnNpemU7XG4gICAgICBpZiAoc2l6ZSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gZW1wdHk7XG4gICAgICB9XG4gICAgICBhc3NlcnROb3RJbmZpbml0ZShzaXplKTtcbiAgICAgIGlmIChzaXplID4gMCAmJiBzaXplIDwgU0laRSkge1xuICAgICAgICByZXR1cm4gbWFrZUxpc3QoMCwgc2l6ZSwgU0hJRlQsIG51bGwsIG5ldyBWTm9kZShpdGVyLnRvQXJyYXkoKSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGVtcHR5LndpdGhNdXRhdGlvbnMoZnVuY3Rpb24obGlzdCApIHtcbiAgICAgICAgbGlzdC5zZXRTaXplKHNpemUpO1xuICAgICAgICBpdGVyLmZvckVhY2goZnVuY3Rpb24odiwgaSkgIHtyZXR1cm4gbGlzdC5zZXQoaSwgdil9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIExpc3Qub2YgPSBmdW5jdGlvbigvKi4uLnZhbHVlcyovKSB7XG4gICAgICByZXR1cm4gdGhpcyhhcmd1bWVudHMpO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX190b1N0cmluZygnTGlzdCBbJywgJ10nKTtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBBY2Nlc3NcblxuICAgIExpc3QucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKGluZGV4LCBub3RTZXRWYWx1ZSkge1xuICAgICAgaW5kZXggPSB3cmFwSW5kZXgodGhpcywgaW5kZXgpO1xuICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCB0aGlzLnNpemUpIHtcbiAgICAgICAgaW5kZXggKz0gdGhpcy5fb3JpZ2luO1xuICAgICAgICB2YXIgbm9kZSA9IGxpc3ROb2RlRm9yKHRoaXMsIGluZGV4KTtcbiAgICAgICAgcmV0dXJuIG5vZGUgJiYgbm9kZS5hcnJheVtpbmRleCAmIE1BU0tdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5vdFNldFZhbHVlO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIE1vZGlmaWNhdGlvblxuXG4gICAgTGlzdC5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24oaW5kZXgsIHZhbHVlKSB7XG4gICAgICByZXR1cm4gdXBkYXRlTGlzdCh0aGlzLCBpbmRleCwgdmFsdWUpO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbihpbmRleCkge1xuICAgICAgcmV0dXJuICF0aGlzLmhhcyhpbmRleCkgPyB0aGlzIDpcbiAgICAgICAgaW5kZXggPT09IDAgPyB0aGlzLnNoaWZ0KCkgOlxuICAgICAgICBpbmRleCA9PT0gdGhpcy5zaXplIC0gMSA/IHRoaXMucG9wKCkgOlxuICAgICAgICB0aGlzLnNwbGljZShpbmRleCwgMSk7XG4gICAgfTtcblxuICAgIExpc3QucHJvdG90eXBlLmluc2VydCA9IGZ1bmN0aW9uKGluZGV4LCB2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuc3BsaWNlKGluZGV4LCAwLCB2YWx1ZSk7XG4gICAgfTtcblxuICAgIExpc3QucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5zaXplID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuX19vd25lcklEKSB7XG4gICAgICAgIHRoaXMuc2l6ZSA9IHRoaXMuX29yaWdpbiA9IHRoaXMuX2NhcGFjaXR5ID0gMDtcbiAgICAgICAgdGhpcy5fbGV2ZWwgPSBTSElGVDtcbiAgICAgICAgdGhpcy5fcm9vdCA9IHRoaXMuX3RhaWwgPSBudWxsO1xuICAgICAgICB0aGlzLl9faGFzaCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fX2FsdGVyZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBlbXB0eUxpc3QoKTtcbiAgICB9O1xuXG4gICAgTGlzdC5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uKC8qLi4udmFsdWVzKi8pIHtcbiAgICAgIHZhciB2YWx1ZXMgPSBhcmd1bWVudHM7XG4gICAgICB2YXIgb2xkU2l6ZSA9IHRoaXMuc2l6ZTtcbiAgICAgIHJldHVybiB0aGlzLndpdGhNdXRhdGlvbnMoZnVuY3Rpb24obGlzdCApIHtcbiAgICAgICAgc2V0TGlzdEJvdW5kcyhsaXN0LCAwLCBvbGRTaXplICsgdmFsdWVzLmxlbmd0aCk7XG4gICAgICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCB2YWx1ZXMubGVuZ3RoOyBpaSsrKSB7XG4gICAgICAgICAgbGlzdC5zZXQob2xkU2l6ZSArIGlpLCB2YWx1ZXNbaWldKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIExpc3QucHJvdG90eXBlLnBvcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHNldExpc3RCb3VuZHModGhpcywgMCwgLTEpO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS51bnNoaWZ0ID0gZnVuY3Rpb24oLyouLi52YWx1ZXMqLykge1xuICAgICAgdmFyIHZhbHVlcyA9IGFyZ3VtZW50cztcbiAgICAgIHJldHVybiB0aGlzLndpdGhNdXRhdGlvbnMoZnVuY3Rpb24obGlzdCApIHtcbiAgICAgICAgc2V0TGlzdEJvdW5kcyhsaXN0LCAtdmFsdWVzLmxlbmd0aCk7XG4gICAgICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCB2YWx1ZXMubGVuZ3RoOyBpaSsrKSB7XG4gICAgICAgICAgbGlzdC5zZXQoaWksIHZhbHVlc1tpaV0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgTGlzdC5wcm90b3R5cGUuc2hpZnQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBzZXRMaXN0Qm91bmRzKHRoaXMsIDEpO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIENvbXBvc2l0aW9uXG5cbiAgICBMaXN0LnByb3RvdHlwZS5tZXJnZSA9IGZ1bmN0aW9uKC8qLi4uaXRlcnMqLykge1xuICAgICAgcmV0dXJuIG1lcmdlSW50b0xpc3RXaXRoKHRoaXMsIHVuZGVmaW5lZCwgYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgTGlzdC5wcm90b3R5cGUubWVyZ2VXaXRoID0gZnVuY3Rpb24obWVyZ2VyKSB7dmFyIGl0ZXJzID0gU0xJQ0UkMC5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICByZXR1cm4gbWVyZ2VJbnRvTGlzdFdpdGgodGhpcywgbWVyZ2VyLCBpdGVycyk7XG4gICAgfTtcblxuICAgIExpc3QucHJvdG90eXBlLm1lcmdlRGVlcCA9IGZ1bmN0aW9uKC8qLi4uaXRlcnMqLykge1xuICAgICAgcmV0dXJuIG1lcmdlSW50b0xpc3RXaXRoKHRoaXMsIGRlZXBNZXJnZXIsIGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIExpc3QucHJvdG90eXBlLm1lcmdlRGVlcFdpdGggPSBmdW5jdGlvbihtZXJnZXIpIHt2YXIgaXRlcnMgPSBTTElDRSQwLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgIHJldHVybiBtZXJnZUludG9MaXN0V2l0aCh0aGlzLCBkZWVwTWVyZ2VyV2l0aChtZXJnZXIpLCBpdGVycyk7XG4gICAgfTtcblxuICAgIExpc3QucHJvdG90eXBlLnNldFNpemUgPSBmdW5jdGlvbihzaXplKSB7XG4gICAgICByZXR1cm4gc2V0TGlzdEJvdW5kcyh0aGlzLCAwLCBzaXplKTtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBJdGVyYXRpb25cblxuICAgIExpc3QucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24oYmVnaW4sIGVuZCkge1xuICAgICAgdmFyIHNpemUgPSB0aGlzLnNpemU7XG4gICAgICBpZiAod2hvbGVTbGljZShiZWdpbiwgZW5kLCBzaXplKSkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBzZXRMaXN0Qm91bmRzKFxuICAgICAgICB0aGlzLFxuICAgICAgICByZXNvbHZlQmVnaW4oYmVnaW4sIHNpemUpLFxuICAgICAgICByZXNvbHZlRW5kKGVuZCwgc2l6ZSlcbiAgICAgICk7XG4gICAgfTtcblxuICAgIExpc3QucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICB2YXIgaW5kZXggPSAwO1xuICAgICAgdmFyIHZhbHVlcyA9IGl0ZXJhdGVMaXN0KHRoaXMsIHJldmVyc2UpO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHZhbHVlcygpO1xuICAgICAgICByZXR1cm4gdmFsdWUgPT09IERPTkUgP1xuICAgICAgICAgIGl0ZXJhdG9yRG9uZSgpIDpcbiAgICAgICAgICBpdGVyYXRvclZhbHVlKHR5cGUsIGluZGV4KyssIHZhbHVlKTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS5fX2l0ZXJhdGUgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge1xuICAgICAgdmFyIGluZGV4ID0gMDtcbiAgICAgIHZhciB2YWx1ZXMgPSBpdGVyYXRlTGlzdCh0aGlzLCByZXZlcnNlKTtcbiAgICAgIHZhciB2YWx1ZTtcbiAgICAgIHdoaWxlICgodmFsdWUgPSB2YWx1ZXMoKSkgIT09IERPTkUpIHtcbiAgICAgICAgaWYgKGZuKHZhbHVlLCBpbmRleCsrLCB0aGlzKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH07XG5cbiAgICBMaXN0LnByb3RvdHlwZS5fX2Vuc3VyZU93bmVyID0gZnVuY3Rpb24ob3duZXJJRCkge1xuICAgICAgaWYgKG93bmVySUQgPT09IHRoaXMuX19vd25lcklEKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgaWYgKCFvd25lcklEKSB7XG4gICAgICAgIHRoaXMuX19vd25lcklEID0gb3duZXJJRDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWFrZUxpc3QodGhpcy5fb3JpZ2luLCB0aGlzLl9jYXBhY2l0eSwgdGhpcy5fbGV2ZWwsIHRoaXMuX3Jvb3QsIHRoaXMuX3RhaWwsIG93bmVySUQsIHRoaXMuX19oYXNoKTtcbiAgICB9O1xuXG5cbiAgZnVuY3Rpb24gaXNMaXN0KG1heWJlTGlzdCkge1xuICAgIHJldHVybiAhIShtYXliZUxpc3QgJiYgbWF5YmVMaXN0W0lTX0xJU1RfU0VOVElORUxdKTtcbiAgfVxuXG4gIExpc3QuaXNMaXN0ID0gaXNMaXN0O1xuXG4gIHZhciBJU19MSVNUX1NFTlRJTkVMID0gJ0BAX19JTU1VVEFCTEVfTElTVF9fQEAnO1xuXG4gIHZhciBMaXN0UHJvdG90eXBlID0gTGlzdC5wcm90b3R5cGU7XG4gIExpc3RQcm90b3R5cGVbSVNfTElTVF9TRU5USU5FTF0gPSB0cnVlO1xuICBMaXN0UHJvdG90eXBlW0RFTEVURV0gPSBMaXN0UHJvdG90eXBlLnJlbW92ZTtcbiAgTGlzdFByb3RvdHlwZS5zZXRJbiA9IE1hcFByb3RvdHlwZS5zZXRJbjtcbiAgTGlzdFByb3RvdHlwZS5kZWxldGVJbiA9XG4gIExpc3RQcm90b3R5cGUucmVtb3ZlSW4gPSBNYXBQcm90b3R5cGUucmVtb3ZlSW47XG4gIExpc3RQcm90b3R5cGUudXBkYXRlID0gTWFwUHJvdG90eXBlLnVwZGF0ZTtcbiAgTGlzdFByb3RvdHlwZS51cGRhdGVJbiA9IE1hcFByb3RvdHlwZS51cGRhdGVJbjtcbiAgTGlzdFByb3RvdHlwZS5tZXJnZUluID0gTWFwUHJvdG90eXBlLm1lcmdlSW47XG4gIExpc3RQcm90b3R5cGUubWVyZ2VEZWVwSW4gPSBNYXBQcm90b3R5cGUubWVyZ2VEZWVwSW47XG4gIExpc3RQcm90b3R5cGUud2l0aE11dGF0aW9ucyA9IE1hcFByb3RvdHlwZS53aXRoTXV0YXRpb25zO1xuICBMaXN0UHJvdG90eXBlLmFzTXV0YWJsZSA9IE1hcFByb3RvdHlwZS5hc011dGFibGU7XG4gIExpc3RQcm90b3R5cGUuYXNJbW11dGFibGUgPSBNYXBQcm90b3R5cGUuYXNJbW11dGFibGU7XG4gIExpc3RQcm90b3R5cGUud2FzQWx0ZXJlZCA9IE1hcFByb3RvdHlwZS53YXNBbHRlcmVkO1xuXG5cblxuICAgIGZ1bmN0aW9uIFZOb2RlKGFycmF5LCBvd25lcklEKSB7XG4gICAgICB0aGlzLmFycmF5ID0gYXJyYXk7XG4gICAgICB0aGlzLm93bmVySUQgPSBvd25lcklEO1xuICAgIH1cblxuICAgIC8vIFRPRE86IHNlZW1zIGxpa2UgdGhlc2UgbWV0aG9kcyBhcmUgdmVyeSBzaW1pbGFyXG5cbiAgICBWTm9kZS5wcm90b3R5cGUucmVtb3ZlQmVmb3JlID0gZnVuY3Rpb24ob3duZXJJRCwgbGV2ZWwsIGluZGV4KSB7XG4gICAgICBpZiAoaW5kZXggPT09IGxldmVsID8gMSA8PCBsZXZlbCA6IDAgfHwgdGhpcy5hcnJheS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICB2YXIgb3JpZ2luSW5kZXggPSAoaW5kZXggPj4+IGxldmVsKSAmIE1BU0s7XG4gICAgICBpZiAob3JpZ2luSW5kZXggPj0gdGhpcy5hcnJheS5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBWTm9kZShbXSwgb3duZXJJRCk7XG4gICAgICB9XG4gICAgICB2YXIgcmVtb3ZpbmdGaXJzdCA9IG9yaWdpbkluZGV4ID09PSAwO1xuICAgICAgdmFyIG5ld0NoaWxkO1xuICAgICAgaWYgKGxldmVsID4gMCkge1xuICAgICAgICB2YXIgb2xkQ2hpbGQgPSB0aGlzLmFycmF5W29yaWdpbkluZGV4XTtcbiAgICAgICAgbmV3Q2hpbGQgPSBvbGRDaGlsZCAmJiBvbGRDaGlsZC5yZW1vdmVCZWZvcmUob3duZXJJRCwgbGV2ZWwgLSBTSElGVCwgaW5kZXgpO1xuICAgICAgICBpZiAobmV3Q2hpbGQgPT09IG9sZENoaWxkICYmIHJlbW92aW5nRmlyc3QpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHJlbW92aW5nRmlyc3QgJiYgIW5ld0NoaWxkKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgdmFyIGVkaXRhYmxlID0gZWRpdGFibGVWTm9kZSh0aGlzLCBvd25lcklEKTtcbiAgICAgIGlmICghcmVtb3ZpbmdGaXJzdCkge1xuICAgICAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgb3JpZ2luSW5kZXg7IGlpKyspIHtcbiAgICAgICAgICBlZGl0YWJsZS5hcnJheVtpaV0gPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChuZXdDaGlsZCkge1xuICAgICAgICBlZGl0YWJsZS5hcnJheVtvcmlnaW5JbmRleF0gPSBuZXdDaGlsZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBlZGl0YWJsZTtcbiAgICB9O1xuXG4gICAgVk5vZGUucHJvdG90eXBlLnJlbW92ZUFmdGVyID0gZnVuY3Rpb24ob3duZXJJRCwgbGV2ZWwsIGluZGV4KSB7XG4gICAgICBpZiAoaW5kZXggPT09IChsZXZlbCA/IDEgPDwgbGV2ZWwgOiAwKSB8fCB0aGlzLmFycmF5Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHZhciBzaXplSW5kZXggPSAoKGluZGV4IC0gMSkgPj4+IGxldmVsKSAmIE1BU0s7XG4gICAgICBpZiAoc2l6ZUluZGV4ID49IHRoaXMuYXJyYXkubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICB2YXIgbmV3Q2hpbGQ7XG4gICAgICBpZiAobGV2ZWwgPiAwKSB7XG4gICAgICAgIHZhciBvbGRDaGlsZCA9IHRoaXMuYXJyYXlbc2l6ZUluZGV4XTtcbiAgICAgICAgbmV3Q2hpbGQgPSBvbGRDaGlsZCAmJiBvbGRDaGlsZC5yZW1vdmVBZnRlcihvd25lcklELCBsZXZlbCAtIFNISUZULCBpbmRleCk7XG4gICAgICAgIGlmIChuZXdDaGlsZCA9PT0gb2xkQ2hpbGQgJiYgc2l6ZUluZGV4ID09PSB0aGlzLmFycmF5Lmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB2YXIgZWRpdGFibGUgPSBlZGl0YWJsZVZOb2RlKHRoaXMsIG93bmVySUQpO1xuICAgICAgZWRpdGFibGUuYXJyYXkuc3BsaWNlKHNpemVJbmRleCArIDEpO1xuICAgICAgaWYgKG5ld0NoaWxkKSB7XG4gICAgICAgIGVkaXRhYmxlLmFycmF5W3NpemVJbmRleF0gPSBuZXdDaGlsZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBlZGl0YWJsZTtcbiAgICB9O1xuXG5cblxuICB2YXIgRE9ORSA9IHt9O1xuXG4gIGZ1bmN0aW9uIGl0ZXJhdGVMaXN0KGxpc3QsIHJldmVyc2UpIHtcbiAgICB2YXIgbGVmdCA9IGxpc3QuX29yaWdpbjtcbiAgICB2YXIgcmlnaHQgPSBsaXN0Ll9jYXBhY2l0eTtcbiAgICB2YXIgdGFpbFBvcyA9IGdldFRhaWxPZmZzZXQocmlnaHQpO1xuICAgIHZhciB0YWlsID0gbGlzdC5fdGFpbDtcblxuICAgIHJldHVybiBpdGVyYXRlTm9kZU9yTGVhZihsaXN0Ll9yb290LCBsaXN0Ll9sZXZlbCwgMCk7XG5cbiAgICBmdW5jdGlvbiBpdGVyYXRlTm9kZU9yTGVhZihub2RlLCBsZXZlbCwgb2Zmc2V0KSB7XG4gICAgICByZXR1cm4gbGV2ZWwgPT09IDAgP1xuICAgICAgICBpdGVyYXRlTGVhZihub2RlLCBvZmZzZXQpIDpcbiAgICAgICAgaXRlcmF0ZU5vZGUobm9kZSwgbGV2ZWwsIG9mZnNldCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXRlcmF0ZUxlYWYobm9kZSwgb2Zmc2V0KSB7XG4gICAgICB2YXIgYXJyYXkgPSBvZmZzZXQgPT09IHRhaWxQb3MgPyB0YWlsICYmIHRhaWwuYXJyYXkgOiBub2RlICYmIG5vZGUuYXJyYXk7XG4gICAgICB2YXIgZnJvbSA9IG9mZnNldCA+IGxlZnQgPyAwIDogbGVmdCAtIG9mZnNldDtcbiAgICAgIHZhciB0byA9IHJpZ2h0IC0gb2Zmc2V0O1xuICAgICAgaWYgKHRvID4gU0laRSkge1xuICAgICAgICB0byA9IFNJWkU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSAge1xuICAgICAgICBpZiAoZnJvbSA9PT0gdG8pIHtcbiAgICAgICAgICByZXR1cm4gRE9ORTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaWR4ID0gcmV2ZXJzZSA/IC0tdG8gOiBmcm9tKys7XG4gICAgICAgIHJldHVybiBhcnJheSAmJiBhcnJheVtpZHhdO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpdGVyYXRlTm9kZShub2RlLCBsZXZlbCwgb2Zmc2V0KSB7XG4gICAgICB2YXIgdmFsdWVzO1xuICAgICAgdmFyIGFycmF5ID0gbm9kZSAmJiBub2RlLmFycmF5O1xuICAgICAgdmFyIGZyb20gPSBvZmZzZXQgPiBsZWZ0ID8gMCA6IChsZWZ0IC0gb2Zmc2V0KSA+PiBsZXZlbDtcbiAgICAgIHZhciB0byA9ICgocmlnaHQgLSBvZmZzZXQpID4+IGxldmVsKSArIDE7XG4gICAgICBpZiAodG8gPiBTSVpFKSB7XG4gICAgICAgIHRvID0gU0laRTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmdW5jdGlvbigpICB7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICBpZiAodmFsdWVzKSB7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSB2YWx1ZXMoKTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gRE9ORSkge1xuICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YWx1ZXMgPSBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZnJvbSA9PT0gdG8pIHtcbiAgICAgICAgICAgIHJldHVybiBET05FO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YXIgaWR4ID0gcmV2ZXJzZSA/IC0tdG8gOiBmcm9tKys7XG4gICAgICAgICAgdmFsdWVzID0gaXRlcmF0ZU5vZGVPckxlYWYoXG4gICAgICAgICAgICBhcnJheSAmJiBhcnJheVtpZHhdLCBsZXZlbCAtIFNISUZULCBvZmZzZXQgKyAoaWR4IDw8IGxldmVsKVxuICAgICAgICAgICk7XG4gICAgICAgIH0gd2hpbGUgKHRydWUpO1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBtYWtlTGlzdChvcmlnaW4sIGNhcGFjaXR5LCBsZXZlbCwgcm9vdCwgdGFpbCwgb3duZXJJRCwgaGFzaCkge1xuICAgIHZhciBsaXN0ID0gT2JqZWN0LmNyZWF0ZShMaXN0UHJvdG90eXBlKTtcbiAgICBsaXN0LnNpemUgPSBjYXBhY2l0eSAtIG9yaWdpbjtcbiAgICBsaXN0Ll9vcmlnaW4gPSBvcmlnaW47XG4gICAgbGlzdC5fY2FwYWNpdHkgPSBjYXBhY2l0eTtcbiAgICBsaXN0Ll9sZXZlbCA9IGxldmVsO1xuICAgIGxpc3QuX3Jvb3QgPSByb290O1xuICAgIGxpc3QuX3RhaWwgPSB0YWlsO1xuICAgIGxpc3QuX19vd25lcklEID0gb3duZXJJRDtcbiAgICBsaXN0Ll9faGFzaCA9IGhhc2g7XG4gICAgbGlzdC5fX2FsdGVyZWQgPSBmYWxzZTtcbiAgICByZXR1cm4gbGlzdDtcbiAgfVxuXG4gIHZhciBFTVBUWV9MSVNUO1xuICBmdW5jdGlvbiBlbXB0eUxpc3QoKSB7XG4gICAgcmV0dXJuIEVNUFRZX0xJU1QgfHwgKEVNUFRZX0xJU1QgPSBtYWtlTGlzdCgwLCAwLCBTSElGVCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlTGlzdChsaXN0LCBpbmRleCwgdmFsdWUpIHtcbiAgICBpbmRleCA9IHdyYXBJbmRleChsaXN0LCBpbmRleCk7XG5cbiAgICBpZiAoaW5kZXggIT09IGluZGV4KSB7XG4gICAgICByZXR1cm4gbGlzdDtcbiAgICB9XG5cbiAgICBpZiAoaW5kZXggPj0gbGlzdC5zaXplIHx8IGluZGV4IDwgMCkge1xuICAgICAgcmV0dXJuIGxpc3Qud2l0aE11dGF0aW9ucyhmdW5jdGlvbihsaXN0ICkge1xuICAgICAgICBpbmRleCA8IDAgP1xuICAgICAgICAgIHNldExpc3RCb3VuZHMobGlzdCwgaW5kZXgpLnNldCgwLCB2YWx1ZSkgOlxuICAgICAgICAgIHNldExpc3RCb3VuZHMobGlzdCwgMCwgaW5kZXggKyAxKS5zZXQoaW5kZXgsIHZhbHVlKVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaW5kZXggKz0gbGlzdC5fb3JpZ2luO1xuXG4gICAgdmFyIG5ld1RhaWwgPSBsaXN0Ll90YWlsO1xuICAgIHZhciBuZXdSb290ID0gbGlzdC5fcm9vdDtcbiAgICB2YXIgZGlkQWx0ZXIgPSBNYWtlUmVmKERJRF9BTFRFUik7XG4gICAgaWYgKGluZGV4ID49IGdldFRhaWxPZmZzZXQobGlzdC5fY2FwYWNpdHkpKSB7XG4gICAgICBuZXdUYWlsID0gdXBkYXRlVk5vZGUobmV3VGFpbCwgbGlzdC5fX293bmVySUQsIDAsIGluZGV4LCB2YWx1ZSwgZGlkQWx0ZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXdSb290ID0gdXBkYXRlVk5vZGUobmV3Um9vdCwgbGlzdC5fX293bmVySUQsIGxpc3QuX2xldmVsLCBpbmRleCwgdmFsdWUsIGRpZEFsdGVyKTtcbiAgICB9XG5cbiAgICBpZiAoIWRpZEFsdGVyLnZhbHVlKSB7XG4gICAgICByZXR1cm4gbGlzdDtcbiAgICB9XG5cbiAgICBpZiAobGlzdC5fX293bmVySUQpIHtcbiAgICAgIGxpc3QuX3Jvb3QgPSBuZXdSb290O1xuICAgICAgbGlzdC5fdGFpbCA9IG5ld1RhaWw7XG4gICAgICBsaXN0Ll9faGFzaCA9IHVuZGVmaW5lZDtcbiAgICAgIGxpc3QuX19hbHRlcmVkID0gdHJ1ZTtcbiAgICAgIHJldHVybiBsaXN0O1xuICAgIH1cbiAgICByZXR1cm4gbWFrZUxpc3QobGlzdC5fb3JpZ2luLCBsaXN0Ll9jYXBhY2l0eSwgbGlzdC5fbGV2ZWwsIG5ld1Jvb3QsIG5ld1RhaWwpO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlVk5vZGUobm9kZSwgb3duZXJJRCwgbGV2ZWwsIGluZGV4LCB2YWx1ZSwgZGlkQWx0ZXIpIHtcbiAgICB2YXIgaWR4ID0gKGluZGV4ID4+PiBsZXZlbCkgJiBNQVNLO1xuICAgIHZhciBub2RlSGFzID0gbm9kZSAmJiBpZHggPCBub2RlLmFycmF5Lmxlbmd0aDtcbiAgICBpZiAoIW5vZGVIYXMgJiYgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfVxuXG4gICAgdmFyIG5ld05vZGU7XG5cbiAgICBpZiAobGV2ZWwgPiAwKSB7XG4gICAgICB2YXIgbG93ZXJOb2RlID0gbm9kZSAmJiBub2RlLmFycmF5W2lkeF07XG4gICAgICB2YXIgbmV3TG93ZXJOb2RlID0gdXBkYXRlVk5vZGUobG93ZXJOb2RlLCBvd25lcklELCBsZXZlbCAtIFNISUZULCBpbmRleCwgdmFsdWUsIGRpZEFsdGVyKTtcbiAgICAgIGlmIChuZXdMb3dlck5vZGUgPT09IGxvd2VyTm9kZSkge1xuICAgICAgICByZXR1cm4gbm9kZTtcbiAgICAgIH1cbiAgICAgIG5ld05vZGUgPSBlZGl0YWJsZVZOb2RlKG5vZGUsIG93bmVySUQpO1xuICAgICAgbmV3Tm9kZS5hcnJheVtpZHhdID0gbmV3TG93ZXJOb2RlO1xuICAgICAgcmV0dXJuIG5ld05vZGU7XG4gICAgfVxuXG4gICAgaWYgKG5vZGVIYXMgJiYgbm9kZS5hcnJheVtpZHhdID09PSB2YWx1ZSkge1xuICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfVxuXG4gICAgU2V0UmVmKGRpZEFsdGVyKTtcblxuICAgIG5ld05vZGUgPSBlZGl0YWJsZVZOb2RlKG5vZGUsIG93bmVySUQpO1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkICYmIGlkeCA9PT0gbmV3Tm9kZS5hcnJheS5sZW5ndGggLSAxKSB7XG4gICAgICBuZXdOb2RlLmFycmF5LnBvcCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXdOb2RlLmFycmF5W2lkeF0gPSB2YWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIG5ld05vZGU7XG4gIH1cblxuICBmdW5jdGlvbiBlZGl0YWJsZVZOb2RlKG5vZGUsIG93bmVySUQpIHtcbiAgICBpZiAob3duZXJJRCAmJiBub2RlICYmIG93bmVySUQgPT09IG5vZGUub3duZXJJRCkge1xuICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfVxuICAgIHJldHVybiBuZXcgVk5vZGUobm9kZSA/IG5vZGUuYXJyYXkuc2xpY2UoKSA6IFtdLCBvd25lcklEKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGxpc3ROb2RlRm9yKGxpc3QsIHJhd0luZGV4KSB7XG4gICAgaWYgKHJhd0luZGV4ID49IGdldFRhaWxPZmZzZXQobGlzdC5fY2FwYWNpdHkpKSB7XG4gICAgICByZXR1cm4gbGlzdC5fdGFpbDtcbiAgICB9XG4gICAgaWYgKHJhd0luZGV4IDwgMSA8PCAobGlzdC5fbGV2ZWwgKyBTSElGVCkpIHtcbiAgICAgIHZhciBub2RlID0gbGlzdC5fcm9vdDtcbiAgICAgIHZhciBsZXZlbCA9IGxpc3QuX2xldmVsO1xuICAgICAgd2hpbGUgKG5vZGUgJiYgbGV2ZWwgPiAwKSB7XG4gICAgICAgIG5vZGUgPSBub2RlLmFycmF5WyhyYXdJbmRleCA+Pj4gbGV2ZWwpICYgTUFTS107XG4gICAgICAgIGxldmVsIC09IFNISUZUO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc2V0TGlzdEJvdW5kcyhsaXN0LCBiZWdpbiwgZW5kKSB7XG4gICAgLy8gU2FuaXRpemUgYmVnaW4gJiBlbmQgdXNpbmcgdGhpcyBzaG9ydGhhbmQgZm9yIFRvSW50MzIoYXJndW1lbnQpXG4gICAgLy8gaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvaW50MzJcbiAgICBpZiAoYmVnaW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgYmVnaW4gPSBiZWdpbiB8IDA7XG4gICAgfVxuICAgIGlmIChlbmQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgZW5kID0gZW5kIHwgMDtcbiAgICB9XG4gICAgdmFyIG93bmVyID0gbGlzdC5fX293bmVySUQgfHwgbmV3IE93bmVySUQoKTtcbiAgICB2YXIgb2xkT3JpZ2luID0gbGlzdC5fb3JpZ2luO1xuICAgIHZhciBvbGRDYXBhY2l0eSA9IGxpc3QuX2NhcGFjaXR5O1xuICAgIHZhciBuZXdPcmlnaW4gPSBvbGRPcmlnaW4gKyBiZWdpbjtcbiAgICB2YXIgbmV3Q2FwYWNpdHkgPSBlbmQgPT09IHVuZGVmaW5lZCA/IG9sZENhcGFjaXR5IDogZW5kIDwgMCA/IG9sZENhcGFjaXR5ICsgZW5kIDogb2xkT3JpZ2luICsgZW5kO1xuICAgIGlmIChuZXdPcmlnaW4gPT09IG9sZE9yaWdpbiAmJiBuZXdDYXBhY2l0eSA9PT0gb2xkQ2FwYWNpdHkpIHtcbiAgICAgIHJldHVybiBsaXN0O1xuICAgIH1cblxuICAgIC8vIElmIGl0J3MgZ29pbmcgdG8gZW5kIGFmdGVyIGl0IHN0YXJ0cywgaXQncyBlbXB0eS5cbiAgICBpZiAobmV3T3JpZ2luID49IG5ld0NhcGFjaXR5KSB7XG4gICAgICByZXR1cm4gbGlzdC5jbGVhcigpO1xuICAgIH1cblxuICAgIHZhciBuZXdMZXZlbCA9IGxpc3QuX2xldmVsO1xuICAgIHZhciBuZXdSb290ID0gbGlzdC5fcm9vdDtcblxuICAgIC8vIE5ldyBvcmlnaW4gbWlnaHQgbmVlZCBjcmVhdGluZyBhIGhpZ2hlciByb290LlxuICAgIHZhciBvZmZzZXRTaGlmdCA9IDA7XG4gICAgd2hpbGUgKG5ld09yaWdpbiArIG9mZnNldFNoaWZ0IDwgMCkge1xuICAgICAgbmV3Um9vdCA9IG5ldyBWTm9kZShuZXdSb290ICYmIG5ld1Jvb3QuYXJyYXkubGVuZ3RoID8gW3VuZGVmaW5lZCwgbmV3Um9vdF0gOiBbXSwgb3duZXIpO1xuICAgICAgbmV3TGV2ZWwgKz0gU0hJRlQ7XG4gICAgICBvZmZzZXRTaGlmdCArPSAxIDw8IG5ld0xldmVsO1xuICAgIH1cbiAgICBpZiAob2Zmc2V0U2hpZnQpIHtcbiAgICAgIG5ld09yaWdpbiArPSBvZmZzZXRTaGlmdDtcbiAgICAgIG9sZE9yaWdpbiArPSBvZmZzZXRTaGlmdDtcbiAgICAgIG5ld0NhcGFjaXR5ICs9IG9mZnNldFNoaWZ0O1xuICAgICAgb2xkQ2FwYWNpdHkgKz0gb2Zmc2V0U2hpZnQ7XG4gICAgfVxuXG4gICAgdmFyIG9sZFRhaWxPZmZzZXQgPSBnZXRUYWlsT2Zmc2V0KG9sZENhcGFjaXR5KTtcbiAgICB2YXIgbmV3VGFpbE9mZnNldCA9IGdldFRhaWxPZmZzZXQobmV3Q2FwYWNpdHkpO1xuXG4gICAgLy8gTmV3IHNpemUgbWlnaHQgbmVlZCBjcmVhdGluZyBhIGhpZ2hlciByb290LlxuICAgIHdoaWxlIChuZXdUYWlsT2Zmc2V0ID49IDEgPDwgKG5ld0xldmVsICsgU0hJRlQpKSB7XG4gICAgICBuZXdSb290ID0gbmV3IFZOb2RlKG5ld1Jvb3QgJiYgbmV3Um9vdC5hcnJheS5sZW5ndGggPyBbbmV3Um9vdF0gOiBbXSwgb3duZXIpO1xuICAgICAgbmV3TGV2ZWwgKz0gU0hJRlQ7XG4gICAgfVxuXG4gICAgLy8gTG9jYXRlIG9yIGNyZWF0ZSB0aGUgbmV3IHRhaWwuXG4gICAgdmFyIG9sZFRhaWwgPSBsaXN0Ll90YWlsO1xuICAgIHZhciBuZXdUYWlsID0gbmV3VGFpbE9mZnNldCA8IG9sZFRhaWxPZmZzZXQgP1xuICAgICAgbGlzdE5vZGVGb3IobGlzdCwgbmV3Q2FwYWNpdHkgLSAxKSA6XG4gICAgICBuZXdUYWlsT2Zmc2V0ID4gb2xkVGFpbE9mZnNldCA/IG5ldyBWTm9kZShbXSwgb3duZXIpIDogb2xkVGFpbDtcblxuICAgIC8vIE1lcmdlIFRhaWwgaW50byB0cmVlLlxuICAgIGlmIChvbGRUYWlsICYmIG5ld1RhaWxPZmZzZXQgPiBvbGRUYWlsT2Zmc2V0ICYmIG5ld09yaWdpbiA8IG9sZENhcGFjaXR5ICYmIG9sZFRhaWwuYXJyYXkubGVuZ3RoKSB7XG4gICAgICBuZXdSb290ID0gZWRpdGFibGVWTm9kZShuZXdSb290LCBvd25lcik7XG4gICAgICB2YXIgbm9kZSA9IG5ld1Jvb3Q7XG4gICAgICBmb3IgKHZhciBsZXZlbCA9IG5ld0xldmVsOyBsZXZlbCA+IFNISUZUOyBsZXZlbCAtPSBTSElGVCkge1xuICAgICAgICB2YXIgaWR4ID0gKG9sZFRhaWxPZmZzZXQgPj4+IGxldmVsKSAmIE1BU0s7XG4gICAgICAgIG5vZGUgPSBub2RlLmFycmF5W2lkeF0gPSBlZGl0YWJsZVZOb2RlKG5vZGUuYXJyYXlbaWR4XSwgb3duZXIpO1xuICAgICAgfVxuICAgICAgbm9kZS5hcnJheVsob2xkVGFpbE9mZnNldCA+Pj4gU0hJRlQpICYgTUFTS10gPSBvbGRUYWlsO1xuICAgIH1cblxuICAgIC8vIElmIHRoZSBzaXplIGhhcyBiZWVuIHJlZHVjZWQsIHRoZXJlJ3MgYSBjaGFuY2UgdGhlIHRhaWwgbmVlZHMgdG8gYmUgdHJpbW1lZC5cbiAgICBpZiAobmV3Q2FwYWNpdHkgPCBvbGRDYXBhY2l0eSkge1xuICAgICAgbmV3VGFpbCA9IG5ld1RhaWwgJiYgbmV3VGFpbC5yZW1vdmVBZnRlcihvd25lciwgMCwgbmV3Q2FwYWNpdHkpO1xuICAgIH1cblxuICAgIC8vIElmIHRoZSBuZXcgb3JpZ2luIGlzIHdpdGhpbiB0aGUgdGFpbCwgdGhlbiB3ZSBkbyBub3QgbmVlZCBhIHJvb3QuXG4gICAgaWYgKG5ld09yaWdpbiA+PSBuZXdUYWlsT2Zmc2V0KSB7XG4gICAgICBuZXdPcmlnaW4gLT0gbmV3VGFpbE9mZnNldDtcbiAgICAgIG5ld0NhcGFjaXR5IC09IG5ld1RhaWxPZmZzZXQ7XG4gICAgICBuZXdMZXZlbCA9IFNISUZUO1xuICAgICAgbmV3Um9vdCA9IG51bGw7XG4gICAgICBuZXdUYWlsID0gbmV3VGFpbCAmJiBuZXdUYWlsLnJlbW92ZUJlZm9yZShvd25lciwgMCwgbmV3T3JpZ2luKTtcblxuICAgIC8vIE90aGVyd2lzZSwgaWYgdGhlIHJvb3QgaGFzIGJlZW4gdHJpbW1lZCwgZ2FyYmFnZSBjb2xsZWN0LlxuICAgIH0gZWxzZSBpZiAobmV3T3JpZ2luID4gb2xkT3JpZ2luIHx8IG5ld1RhaWxPZmZzZXQgPCBvbGRUYWlsT2Zmc2V0KSB7XG4gICAgICBvZmZzZXRTaGlmdCA9IDA7XG5cbiAgICAgIC8vIElkZW50aWZ5IHRoZSBuZXcgdG9wIHJvb3Qgbm9kZSBvZiB0aGUgc3VidHJlZSBvZiB0aGUgb2xkIHJvb3QuXG4gICAgICB3aGlsZSAobmV3Um9vdCkge1xuICAgICAgICB2YXIgYmVnaW5JbmRleCA9IChuZXdPcmlnaW4gPj4+IG5ld0xldmVsKSAmIE1BU0s7XG4gICAgICAgIGlmIChiZWdpbkluZGV4ICE9PSAobmV3VGFpbE9mZnNldCA+Pj4gbmV3TGV2ZWwpICYgTUFTSykge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChiZWdpbkluZGV4KSB7XG4gICAgICAgICAgb2Zmc2V0U2hpZnQgKz0gKDEgPDwgbmV3TGV2ZWwpICogYmVnaW5JbmRleDtcbiAgICAgICAgfVxuICAgICAgICBuZXdMZXZlbCAtPSBTSElGVDtcbiAgICAgICAgbmV3Um9vdCA9IG5ld1Jvb3QuYXJyYXlbYmVnaW5JbmRleF07XG4gICAgICB9XG5cbiAgICAgIC8vIFRyaW0gdGhlIG5ldyBzaWRlcyBvZiB0aGUgbmV3IHJvb3QuXG4gICAgICBpZiAobmV3Um9vdCAmJiBuZXdPcmlnaW4gPiBvbGRPcmlnaW4pIHtcbiAgICAgICAgbmV3Um9vdCA9IG5ld1Jvb3QucmVtb3ZlQmVmb3JlKG93bmVyLCBuZXdMZXZlbCwgbmV3T3JpZ2luIC0gb2Zmc2V0U2hpZnQpO1xuICAgICAgfVxuICAgICAgaWYgKG5ld1Jvb3QgJiYgbmV3VGFpbE9mZnNldCA8IG9sZFRhaWxPZmZzZXQpIHtcbiAgICAgICAgbmV3Um9vdCA9IG5ld1Jvb3QucmVtb3ZlQWZ0ZXIob3duZXIsIG5ld0xldmVsLCBuZXdUYWlsT2Zmc2V0IC0gb2Zmc2V0U2hpZnQpO1xuICAgICAgfVxuICAgICAgaWYgKG9mZnNldFNoaWZ0KSB7XG4gICAgICAgIG5ld09yaWdpbiAtPSBvZmZzZXRTaGlmdDtcbiAgICAgICAgbmV3Q2FwYWNpdHkgLT0gb2Zmc2V0U2hpZnQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGxpc3QuX19vd25lcklEKSB7XG4gICAgICBsaXN0LnNpemUgPSBuZXdDYXBhY2l0eSAtIG5ld09yaWdpbjtcbiAgICAgIGxpc3QuX29yaWdpbiA9IG5ld09yaWdpbjtcbiAgICAgIGxpc3QuX2NhcGFjaXR5ID0gbmV3Q2FwYWNpdHk7XG4gICAgICBsaXN0Ll9sZXZlbCA9IG5ld0xldmVsO1xuICAgICAgbGlzdC5fcm9vdCA9IG5ld1Jvb3Q7XG4gICAgICBsaXN0Ll90YWlsID0gbmV3VGFpbDtcbiAgICAgIGxpc3QuX19oYXNoID0gdW5kZWZpbmVkO1xuICAgICAgbGlzdC5fX2FsdGVyZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuIGxpc3Q7XG4gICAgfVxuICAgIHJldHVybiBtYWtlTGlzdChuZXdPcmlnaW4sIG5ld0NhcGFjaXR5LCBuZXdMZXZlbCwgbmV3Um9vdCwgbmV3VGFpbCk7XG4gIH1cblxuICBmdW5jdGlvbiBtZXJnZUludG9MaXN0V2l0aChsaXN0LCBtZXJnZXIsIGl0ZXJhYmxlcykge1xuICAgIHZhciBpdGVycyA9IFtdO1xuICAgIHZhciBtYXhTaXplID0gMDtcbiAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgaXRlcmFibGVzLmxlbmd0aDsgaWkrKykge1xuICAgICAgdmFyIHZhbHVlID0gaXRlcmFibGVzW2lpXTtcbiAgICAgIHZhciBpdGVyID0gSW5kZXhlZEl0ZXJhYmxlKHZhbHVlKTtcbiAgICAgIGlmIChpdGVyLnNpemUgPiBtYXhTaXplKSB7XG4gICAgICAgIG1heFNpemUgPSBpdGVyLnNpemU7XG4gICAgICB9XG4gICAgICBpZiAoIWlzSXRlcmFibGUodmFsdWUpKSB7XG4gICAgICAgIGl0ZXIgPSBpdGVyLm1hcChmdW5jdGlvbih2ICkge3JldHVybiBmcm9tSlModil9KTtcbiAgICAgIH1cbiAgICAgIGl0ZXJzLnB1c2goaXRlcik7XG4gICAgfVxuICAgIGlmIChtYXhTaXplID4gbGlzdC5zaXplKSB7XG4gICAgICBsaXN0ID0gbGlzdC5zZXRTaXplKG1heFNpemUpO1xuICAgIH1cbiAgICByZXR1cm4gbWVyZ2VJbnRvQ29sbGVjdGlvbldpdGgobGlzdCwgbWVyZ2VyLCBpdGVycyk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRUYWlsT2Zmc2V0KHNpemUpIHtcbiAgICByZXR1cm4gc2l6ZSA8IFNJWkUgPyAwIDogKCgoc2l6ZSAtIDEpID4+PiBTSElGVCkgPDwgU0hJRlQpO1xuICB9XG5cbiAgY3JlYXRlQ2xhc3MoT3JkZXJlZE1hcCwgTWFwKTtcblxuICAgIC8vIEBwcmFnbWEgQ29uc3RydWN0aW9uXG5cbiAgICBmdW5jdGlvbiBPcmRlcmVkTWFwKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCA/IGVtcHR5T3JkZXJlZE1hcCgpIDpcbiAgICAgICAgaXNPcmRlcmVkTWFwKHZhbHVlKSA/IHZhbHVlIDpcbiAgICAgICAgZW1wdHlPcmRlcmVkTWFwKCkud2l0aE11dGF0aW9ucyhmdW5jdGlvbihtYXAgKSB7XG4gICAgICAgICAgdmFyIGl0ZXIgPSBLZXllZEl0ZXJhYmxlKHZhbHVlKTtcbiAgICAgICAgICBhc3NlcnROb3RJbmZpbml0ZShpdGVyLnNpemUpO1xuICAgICAgICAgIGl0ZXIuZm9yRWFjaChmdW5jdGlvbih2LCBrKSAge3JldHVybiBtYXAuc2V0KGssIHYpfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIE9yZGVyZWRNYXAub2YgPSBmdW5jdGlvbigvKi4uLnZhbHVlcyovKSB7XG4gICAgICByZXR1cm4gdGhpcyhhcmd1bWVudHMpO1xuICAgIH07XG5cbiAgICBPcmRlcmVkTWFwLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX190b1N0cmluZygnT3JkZXJlZE1hcCB7JywgJ30nKTtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBBY2Nlc3NcblxuICAgIE9yZGVyZWRNYXAucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKGssIG5vdFNldFZhbHVlKSB7XG4gICAgICB2YXIgaW5kZXggPSB0aGlzLl9tYXAuZ2V0KGspO1xuICAgICAgcmV0dXJuIGluZGV4ICE9PSB1bmRlZmluZWQgPyB0aGlzLl9saXN0LmdldChpbmRleClbMV0gOiBub3RTZXRWYWx1ZTtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBNb2RpZmljYXRpb25cblxuICAgIE9yZGVyZWRNYXAucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5zaXplID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuX19vd25lcklEKSB7XG4gICAgICAgIHRoaXMuc2l6ZSA9IDA7XG4gICAgICAgIHRoaXMuX21hcC5jbGVhcigpO1xuICAgICAgICB0aGlzLl9saXN0LmNsZWFyKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGVtcHR5T3JkZXJlZE1hcCgpO1xuICAgIH07XG5cbiAgICBPcmRlcmVkTWFwLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbihrLCB2KSB7XG4gICAgICByZXR1cm4gdXBkYXRlT3JkZXJlZE1hcCh0aGlzLCBrLCB2KTtcbiAgICB9O1xuXG4gICAgT3JkZXJlZE1hcC5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24oaykge1xuICAgICAgcmV0dXJuIHVwZGF0ZU9yZGVyZWRNYXAodGhpcywgaywgTk9UX1NFVCk7XG4gICAgfTtcblxuICAgIE9yZGVyZWRNYXAucHJvdG90eXBlLndhc0FsdGVyZWQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9tYXAud2FzQWx0ZXJlZCgpIHx8IHRoaXMuX2xpc3Qud2FzQWx0ZXJlZCgpO1xuICAgIH07XG5cbiAgICBPcmRlcmVkTWFwLnByb3RvdHlwZS5fX2l0ZXJhdGUgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgcmV0dXJuIHRoaXMuX2xpc3QuX19pdGVyYXRlKFxuICAgICAgICBmdW5jdGlvbihlbnRyeSApIHtyZXR1cm4gZW50cnkgJiYgZm4oZW50cnlbMV0sIGVudHJ5WzBdLCB0aGlzJDApfSxcbiAgICAgICAgcmV2ZXJzZVxuICAgICAgKTtcbiAgICB9O1xuXG4gICAgT3JkZXJlZE1hcC5wcm90b3R5cGUuX19pdGVyYXRvciA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIHJldHVybiB0aGlzLl9saXN0LmZyb21FbnRyeVNlcSgpLl9faXRlcmF0b3IodHlwZSwgcmV2ZXJzZSk7XG4gICAgfTtcblxuICAgIE9yZGVyZWRNYXAucHJvdG90eXBlLl9fZW5zdXJlT3duZXIgPSBmdW5jdGlvbihvd25lcklEKSB7XG4gICAgICBpZiAob3duZXJJRCA9PT0gdGhpcy5fX293bmVySUQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICB2YXIgbmV3TWFwID0gdGhpcy5fbWFwLl9fZW5zdXJlT3duZXIob3duZXJJRCk7XG4gICAgICB2YXIgbmV3TGlzdCA9IHRoaXMuX2xpc3QuX19lbnN1cmVPd25lcihvd25lcklEKTtcbiAgICAgIGlmICghb3duZXJJRCkge1xuICAgICAgICB0aGlzLl9fb3duZXJJRCA9IG93bmVySUQ7XG4gICAgICAgIHRoaXMuX21hcCA9IG5ld01hcDtcbiAgICAgICAgdGhpcy5fbGlzdCA9IG5ld0xpc3Q7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1ha2VPcmRlcmVkTWFwKG5ld01hcCwgbmV3TGlzdCwgb3duZXJJRCwgdGhpcy5fX2hhc2gpO1xuICAgIH07XG5cblxuICBmdW5jdGlvbiBpc09yZGVyZWRNYXAobWF5YmVPcmRlcmVkTWFwKSB7XG4gICAgcmV0dXJuIGlzTWFwKG1heWJlT3JkZXJlZE1hcCkgJiYgaXNPcmRlcmVkKG1heWJlT3JkZXJlZE1hcCk7XG4gIH1cblxuICBPcmRlcmVkTWFwLmlzT3JkZXJlZE1hcCA9IGlzT3JkZXJlZE1hcDtcblxuICBPcmRlcmVkTWFwLnByb3RvdHlwZVtJU19PUkRFUkVEX1NFTlRJTkVMXSA9IHRydWU7XG4gIE9yZGVyZWRNYXAucHJvdG90eXBlW0RFTEVURV0gPSBPcmRlcmVkTWFwLnByb3RvdHlwZS5yZW1vdmU7XG5cblxuXG4gIGZ1bmN0aW9uIG1ha2VPcmRlcmVkTWFwKG1hcCwgbGlzdCwgb3duZXJJRCwgaGFzaCkge1xuICAgIHZhciBvbWFwID0gT2JqZWN0LmNyZWF0ZShPcmRlcmVkTWFwLnByb3RvdHlwZSk7XG4gICAgb21hcC5zaXplID0gbWFwID8gbWFwLnNpemUgOiAwO1xuICAgIG9tYXAuX21hcCA9IG1hcDtcbiAgICBvbWFwLl9saXN0ID0gbGlzdDtcbiAgICBvbWFwLl9fb3duZXJJRCA9IG93bmVySUQ7XG4gICAgb21hcC5fX2hhc2ggPSBoYXNoO1xuICAgIHJldHVybiBvbWFwO1xuICB9XG5cbiAgdmFyIEVNUFRZX09SREVSRURfTUFQO1xuICBmdW5jdGlvbiBlbXB0eU9yZGVyZWRNYXAoKSB7XG4gICAgcmV0dXJuIEVNUFRZX09SREVSRURfTUFQIHx8IChFTVBUWV9PUkRFUkVEX01BUCA9IG1ha2VPcmRlcmVkTWFwKGVtcHR5TWFwKCksIGVtcHR5TGlzdCgpKSk7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVPcmRlcmVkTWFwKG9tYXAsIGssIHYpIHtcbiAgICB2YXIgbWFwID0gb21hcC5fbWFwO1xuICAgIHZhciBsaXN0ID0gb21hcC5fbGlzdDtcbiAgICB2YXIgaSA9IG1hcC5nZXQoayk7XG4gICAgdmFyIGhhcyA9IGkgIT09IHVuZGVmaW5lZDtcbiAgICB2YXIgbmV3TWFwO1xuICAgIHZhciBuZXdMaXN0O1xuICAgIGlmICh2ID09PSBOT1RfU0VUKSB7IC8vIHJlbW92ZWRcbiAgICAgIGlmICghaGFzKSB7XG4gICAgICAgIHJldHVybiBvbWFwO1xuICAgICAgfVxuICAgICAgaWYgKGxpc3Quc2l6ZSA+PSBTSVpFICYmIGxpc3Quc2l6ZSA+PSBtYXAuc2l6ZSAqIDIpIHtcbiAgICAgICAgbmV3TGlzdCA9IGxpc3QuZmlsdGVyKGZ1bmN0aW9uKGVudHJ5LCBpZHgpICB7cmV0dXJuIGVudHJ5ICE9PSB1bmRlZmluZWQgJiYgaSAhPT0gaWR4fSk7XG4gICAgICAgIG5ld01hcCA9IG5ld0xpc3QudG9LZXllZFNlcSgpLm1hcChmdW5jdGlvbihlbnRyeSApIHtyZXR1cm4gZW50cnlbMF19KS5mbGlwKCkudG9NYXAoKTtcbiAgICAgICAgaWYgKG9tYXAuX19vd25lcklEKSB7XG4gICAgICAgICAgbmV3TWFwLl9fb3duZXJJRCA9IG5ld0xpc3QuX19vd25lcklEID0gb21hcC5fX293bmVySUQ7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5ld01hcCA9IG1hcC5yZW1vdmUoayk7XG4gICAgICAgIG5ld0xpc3QgPSBpID09PSBsaXN0LnNpemUgLSAxID8gbGlzdC5wb3AoKSA6IGxpc3Quc2V0KGksIHVuZGVmaW5lZCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChoYXMpIHtcbiAgICAgICAgaWYgKHYgPT09IGxpc3QuZ2V0KGkpWzFdKSB7XG4gICAgICAgICAgcmV0dXJuIG9tYXA7XG4gICAgICAgIH1cbiAgICAgICAgbmV3TWFwID0gbWFwO1xuICAgICAgICBuZXdMaXN0ID0gbGlzdC5zZXQoaSwgW2ssIHZdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5ld01hcCA9IG1hcC5zZXQoaywgbGlzdC5zaXplKTtcbiAgICAgICAgbmV3TGlzdCA9IGxpc3Quc2V0KGxpc3Quc2l6ZSwgW2ssIHZdKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKG9tYXAuX19vd25lcklEKSB7XG4gICAgICBvbWFwLnNpemUgPSBuZXdNYXAuc2l6ZTtcbiAgICAgIG9tYXAuX21hcCA9IG5ld01hcDtcbiAgICAgIG9tYXAuX2xpc3QgPSBuZXdMaXN0O1xuICAgICAgb21hcC5fX2hhc2ggPSB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gb21hcDtcbiAgICB9XG4gICAgcmV0dXJuIG1ha2VPcmRlcmVkTWFwKG5ld01hcCwgbmV3TGlzdCk7XG4gIH1cblxuICBjcmVhdGVDbGFzcyhUb0tleWVkU2VxdWVuY2UsIEtleWVkU2VxKTtcbiAgICBmdW5jdGlvbiBUb0tleWVkU2VxdWVuY2UoaW5kZXhlZCwgdXNlS2V5cykge1xuICAgICAgdGhpcy5faXRlciA9IGluZGV4ZWQ7XG4gICAgICB0aGlzLl91c2VLZXlzID0gdXNlS2V5cztcbiAgICAgIHRoaXMuc2l6ZSA9IGluZGV4ZWQuc2l6ZTtcbiAgICB9XG5cbiAgICBUb0tleWVkU2VxdWVuY2UucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKGtleSwgbm90U2V0VmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLl9pdGVyLmdldChrZXksIG5vdFNldFZhbHVlKTtcbiAgICB9O1xuXG4gICAgVG9LZXllZFNlcXVlbmNlLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9pdGVyLmhhcyhrZXkpO1xuICAgIH07XG5cbiAgICBUb0tleWVkU2VxdWVuY2UucHJvdG90eXBlLnZhbHVlU2VxID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5faXRlci52YWx1ZVNlcSgpO1xuICAgIH07XG5cbiAgICBUb0tleWVkU2VxdWVuY2UucHJvdG90eXBlLnJldmVyc2UgPSBmdW5jdGlvbigpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIHZhciByZXZlcnNlZFNlcXVlbmNlID0gcmV2ZXJzZUZhY3RvcnkodGhpcywgdHJ1ZSk7XG4gICAgICBpZiAoIXRoaXMuX3VzZUtleXMpIHtcbiAgICAgICAgcmV2ZXJzZWRTZXF1ZW5jZS52YWx1ZVNlcSA9IGZ1bmN0aW9uKCkgIHtyZXR1cm4gdGhpcyQwLl9pdGVyLnRvU2VxKCkucmV2ZXJzZSgpfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXZlcnNlZFNlcXVlbmNlO1xuICAgIH07XG5cbiAgICBUb0tleWVkU2VxdWVuY2UucHJvdG90eXBlLm1hcCA9IGZ1bmN0aW9uKG1hcHBlciwgY29udGV4dCkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgdmFyIG1hcHBlZFNlcXVlbmNlID0gbWFwRmFjdG9yeSh0aGlzLCBtYXBwZXIsIGNvbnRleHQpO1xuICAgICAgaWYgKCF0aGlzLl91c2VLZXlzKSB7XG4gICAgICAgIG1hcHBlZFNlcXVlbmNlLnZhbHVlU2VxID0gZnVuY3Rpb24oKSAge3JldHVybiB0aGlzJDAuX2l0ZXIudG9TZXEoKS5tYXAobWFwcGVyLCBjb250ZXh0KX07XG4gICAgICB9XG4gICAgICByZXR1cm4gbWFwcGVkU2VxdWVuY2U7XG4gICAgfTtcblxuICAgIFRvS2V5ZWRTZXF1ZW5jZS5wcm90b3R5cGUuX19pdGVyYXRlID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIHZhciBpaTtcbiAgICAgIHJldHVybiB0aGlzLl9pdGVyLl9faXRlcmF0ZShcbiAgICAgICAgdGhpcy5fdXNlS2V5cyA/XG4gICAgICAgICAgZnVuY3Rpb24odiwgaykgIHtyZXR1cm4gZm4odiwgaywgdGhpcyQwKX0gOlxuICAgICAgICAgICgoaWkgPSByZXZlcnNlID8gcmVzb2x2ZVNpemUodGhpcykgOiAwKSxcbiAgICAgICAgICAgIGZ1bmN0aW9uKHYgKSB7cmV0dXJuIGZuKHYsIHJldmVyc2UgPyAtLWlpIDogaWkrKywgdGhpcyQwKX0pLFxuICAgICAgICByZXZlcnNlXG4gICAgICApO1xuICAgIH07XG5cbiAgICBUb0tleWVkU2VxdWVuY2UucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICBpZiAodGhpcy5fdXNlS2V5cykge1xuICAgICAgICByZXR1cm4gdGhpcy5faXRlci5fX2l0ZXJhdG9yKHR5cGUsIHJldmVyc2UpO1xuICAgICAgfVxuICAgICAgdmFyIGl0ZXJhdG9yID0gdGhpcy5faXRlci5fX2l0ZXJhdG9yKElURVJBVEVfVkFMVUVTLCByZXZlcnNlKTtcbiAgICAgIHZhciBpaSA9IHJldmVyc2UgPyByZXNvbHZlU2l6ZSh0aGlzKSA6IDA7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgdmFyIHN0ZXAgPSBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgIHJldHVybiBzdGVwLmRvbmUgPyBzdGVwIDpcbiAgICAgICAgICBpdGVyYXRvclZhbHVlKHR5cGUsIHJldmVyc2UgPyAtLWlpIDogaWkrKywgc3RlcC52YWx1ZSwgc3RlcCk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gIFRvS2V5ZWRTZXF1ZW5jZS5wcm90b3R5cGVbSVNfT1JERVJFRF9TRU5USU5FTF0gPSB0cnVlO1xuXG5cbiAgY3JlYXRlQ2xhc3MoVG9JbmRleGVkU2VxdWVuY2UsIEluZGV4ZWRTZXEpO1xuICAgIGZ1bmN0aW9uIFRvSW5kZXhlZFNlcXVlbmNlKGl0ZXIpIHtcbiAgICAgIHRoaXMuX2l0ZXIgPSBpdGVyO1xuICAgICAgdGhpcy5zaXplID0gaXRlci5zaXplO1xuICAgIH1cblxuICAgIFRvSW5kZXhlZFNlcXVlbmNlLnByb3RvdHlwZS5pbmNsdWRlcyA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5faXRlci5pbmNsdWRlcyh2YWx1ZSk7XG4gICAgfTtcblxuICAgIFRvSW5kZXhlZFNlcXVlbmNlLnByb3RvdHlwZS5fX2l0ZXJhdGUgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgcmV0dXJuIHRoaXMuX2l0ZXIuX19pdGVyYXRlKGZ1bmN0aW9uKHYgKSB7cmV0dXJuIGZuKHYsIGl0ZXJhdGlvbnMrKywgdGhpcyQwKX0sIHJldmVyc2UpO1xuICAgIH07XG5cbiAgICBUb0luZGV4ZWRTZXF1ZW5jZS5wcm90b3R5cGUuX19pdGVyYXRvciA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIHZhciBpdGVyYXRvciA9IHRoaXMuX2l0ZXIuX19pdGVyYXRvcihJVEVSQVRFX1ZBTFVFUywgcmV2ZXJzZSk7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgdmFyIHN0ZXAgPSBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgIHJldHVybiBzdGVwLmRvbmUgPyBzdGVwIDpcbiAgICAgICAgICBpdGVyYXRvclZhbHVlKHR5cGUsIGl0ZXJhdGlvbnMrKywgc3RlcC52YWx1ZSwgc3RlcClcbiAgICAgIH0pO1xuICAgIH07XG5cblxuXG4gIGNyZWF0ZUNsYXNzKFRvU2V0U2VxdWVuY2UsIFNldFNlcSk7XG4gICAgZnVuY3Rpb24gVG9TZXRTZXF1ZW5jZShpdGVyKSB7XG4gICAgICB0aGlzLl9pdGVyID0gaXRlcjtcbiAgICAgIHRoaXMuc2l6ZSA9IGl0ZXIuc2l6ZTtcbiAgICB9XG5cbiAgICBUb1NldFNlcXVlbmNlLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9pdGVyLmluY2x1ZGVzKGtleSk7XG4gICAgfTtcblxuICAgIFRvU2V0U2VxdWVuY2UucHJvdG90eXBlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICByZXR1cm4gdGhpcy5faXRlci5fX2l0ZXJhdGUoZnVuY3Rpb24odiApIHtyZXR1cm4gZm4odiwgdiwgdGhpcyQwKX0sIHJldmVyc2UpO1xuICAgIH07XG5cbiAgICBUb1NldFNlcXVlbmNlLnByb3RvdHlwZS5fX2l0ZXJhdG9yID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgdmFyIGl0ZXJhdG9yID0gdGhpcy5faXRlci5fX2l0ZXJhdG9yKElURVJBVEVfVkFMVUVTLCByZXZlcnNlKTtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSAge1xuICAgICAgICB2YXIgc3RlcCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgcmV0dXJuIHN0ZXAuZG9uZSA/IHN0ZXAgOlxuICAgICAgICAgIGl0ZXJhdG9yVmFsdWUodHlwZSwgc3RlcC52YWx1ZSwgc3RlcC52YWx1ZSwgc3RlcCk7XG4gICAgICB9KTtcbiAgICB9O1xuXG5cblxuICBjcmVhdGVDbGFzcyhGcm9tRW50cmllc1NlcXVlbmNlLCBLZXllZFNlcSk7XG4gICAgZnVuY3Rpb24gRnJvbUVudHJpZXNTZXF1ZW5jZShlbnRyaWVzKSB7XG4gICAgICB0aGlzLl9pdGVyID0gZW50cmllcztcbiAgICAgIHRoaXMuc2l6ZSA9IGVudHJpZXMuc2l6ZTtcbiAgICB9XG5cbiAgICBGcm9tRW50cmllc1NlcXVlbmNlLnByb3RvdHlwZS5lbnRyeVNlcSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2l0ZXIudG9TZXEoKTtcbiAgICB9O1xuXG4gICAgRnJvbUVudHJpZXNTZXF1ZW5jZS5wcm90b3R5cGUuX19pdGVyYXRlID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIHJldHVybiB0aGlzLl9pdGVyLl9faXRlcmF0ZShmdW5jdGlvbihlbnRyeSApIHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgZW50cnkgZXhpc3RzIGZpcnN0IHNvIGFycmF5IGFjY2VzcyBkb2Vzbid0IHRocm93IGZvciBob2xlc1xuICAgICAgICAvLyBpbiB0aGUgcGFyZW50IGl0ZXJhdGlvbi5cbiAgICAgICAgaWYgKGVudHJ5KSB7XG4gICAgICAgICAgdmFsaWRhdGVFbnRyeShlbnRyeSk7XG4gICAgICAgICAgdmFyIGluZGV4ZWRJdGVyYWJsZSA9IGlzSXRlcmFibGUoZW50cnkpO1xuICAgICAgICAgIHJldHVybiBmbihcbiAgICAgICAgICAgIGluZGV4ZWRJdGVyYWJsZSA/IGVudHJ5LmdldCgxKSA6IGVudHJ5WzFdLFxuICAgICAgICAgICAgaW5kZXhlZEl0ZXJhYmxlID8gZW50cnkuZ2V0KDApIDogZW50cnlbMF0sXG4gICAgICAgICAgICB0aGlzJDBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9LCByZXZlcnNlKTtcbiAgICB9O1xuXG4gICAgRnJvbUVudHJpZXNTZXF1ZW5jZS5wcm90b3R5cGUuX19pdGVyYXRvciA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIHZhciBpdGVyYXRvciA9IHRoaXMuX2l0ZXIuX19pdGVyYXRvcihJVEVSQVRFX1ZBTFVFUywgcmV2ZXJzZSk7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICB2YXIgc3RlcCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgICBpZiAoc3RlcC5kb25lKSB7XG4gICAgICAgICAgICByZXR1cm4gc3RlcDtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIGVudHJ5ID0gc3RlcC52YWx1ZTtcbiAgICAgICAgICAvLyBDaGVjayBpZiBlbnRyeSBleGlzdHMgZmlyc3Qgc28gYXJyYXkgYWNjZXNzIGRvZXNuJ3QgdGhyb3cgZm9yIGhvbGVzXG4gICAgICAgICAgLy8gaW4gdGhlIHBhcmVudCBpdGVyYXRpb24uXG4gICAgICAgICAgaWYgKGVudHJ5KSB7XG4gICAgICAgICAgICB2YWxpZGF0ZUVudHJ5KGVudHJ5KTtcbiAgICAgICAgICAgIHZhciBpbmRleGVkSXRlcmFibGUgPSBpc0l0ZXJhYmxlKGVudHJ5KTtcbiAgICAgICAgICAgIHJldHVybiBpdGVyYXRvclZhbHVlKFxuICAgICAgICAgICAgICB0eXBlLFxuICAgICAgICAgICAgICBpbmRleGVkSXRlcmFibGUgPyBlbnRyeS5nZXQoMCkgOiBlbnRyeVswXSxcbiAgICAgICAgICAgICAgaW5kZXhlZEl0ZXJhYmxlID8gZW50cnkuZ2V0KDEpIDogZW50cnlbMV0sXG4gICAgICAgICAgICAgIHN0ZXBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuXG5cbiAgVG9JbmRleGVkU2VxdWVuY2UucHJvdG90eXBlLmNhY2hlUmVzdWx0ID1cbiAgVG9LZXllZFNlcXVlbmNlLnByb3RvdHlwZS5jYWNoZVJlc3VsdCA9XG4gIFRvU2V0U2VxdWVuY2UucHJvdG90eXBlLmNhY2hlUmVzdWx0ID1cbiAgRnJvbUVudHJpZXNTZXF1ZW5jZS5wcm90b3R5cGUuY2FjaGVSZXN1bHQgPVxuICAgIGNhY2hlUmVzdWx0VGhyb3VnaDtcblxuXG4gIGZ1bmN0aW9uIGZsaXBGYWN0b3J5KGl0ZXJhYmxlKSB7XG4gICAgdmFyIGZsaXBTZXF1ZW5jZSA9IG1ha2VTZXF1ZW5jZShpdGVyYWJsZSk7XG4gICAgZmxpcFNlcXVlbmNlLl9pdGVyID0gaXRlcmFibGU7XG4gICAgZmxpcFNlcXVlbmNlLnNpemUgPSBpdGVyYWJsZS5zaXplO1xuICAgIGZsaXBTZXF1ZW5jZS5mbGlwID0gZnVuY3Rpb24oKSAge3JldHVybiBpdGVyYWJsZX07XG4gICAgZmxpcFNlcXVlbmNlLnJldmVyc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgcmV2ZXJzZWRTZXF1ZW5jZSA9IGl0ZXJhYmxlLnJldmVyc2UuYXBwbHkodGhpcyk7IC8vIHN1cGVyLnJldmVyc2UoKVxuICAgICAgcmV2ZXJzZWRTZXF1ZW5jZS5mbGlwID0gZnVuY3Rpb24oKSAge3JldHVybiBpdGVyYWJsZS5yZXZlcnNlKCl9O1xuICAgICAgcmV0dXJuIHJldmVyc2VkU2VxdWVuY2U7XG4gICAgfTtcbiAgICBmbGlwU2VxdWVuY2UuaGFzID0gZnVuY3Rpb24oa2V5ICkge3JldHVybiBpdGVyYWJsZS5pbmNsdWRlcyhrZXkpfTtcbiAgICBmbGlwU2VxdWVuY2UuaW5jbHVkZXMgPSBmdW5jdGlvbihrZXkgKSB7cmV0dXJuIGl0ZXJhYmxlLmhhcyhrZXkpfTtcbiAgICBmbGlwU2VxdWVuY2UuY2FjaGVSZXN1bHQgPSBjYWNoZVJlc3VsdFRocm91Z2g7XG4gICAgZmxpcFNlcXVlbmNlLl9faXRlcmF0ZVVuY2FjaGVkID0gZnVuY3Rpb24gKGZuLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICByZXR1cm4gaXRlcmFibGUuX19pdGVyYXRlKGZ1bmN0aW9uKHYsIGspICB7cmV0dXJuIGZuKGssIHYsIHRoaXMkMCkgIT09IGZhbHNlfSwgcmV2ZXJzZSk7XG4gICAgfVxuICAgIGZsaXBTZXF1ZW5jZS5fX2l0ZXJhdG9yVW5jYWNoZWQgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICBpZiAodHlwZSA9PT0gSVRFUkFURV9FTlRSSUVTKSB7XG4gICAgICAgIHZhciBpdGVyYXRvciA9IGl0ZXJhYmxlLl9faXRlcmF0b3IodHlwZSwgcmV2ZXJzZSk7XG4gICAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSAge1xuICAgICAgICAgIHZhciBzdGVwID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICAgIGlmICghc3RlcC5kb25lKSB7XG4gICAgICAgICAgICB2YXIgayA9IHN0ZXAudmFsdWVbMF07XG4gICAgICAgICAgICBzdGVwLnZhbHVlWzBdID0gc3RlcC52YWx1ZVsxXTtcbiAgICAgICAgICAgIHN0ZXAudmFsdWVbMV0gPSBrO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gc3RlcDtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gaXRlcmFibGUuX19pdGVyYXRvcihcbiAgICAgICAgdHlwZSA9PT0gSVRFUkFURV9WQUxVRVMgPyBJVEVSQVRFX0tFWVMgOiBJVEVSQVRFX1ZBTFVFUyxcbiAgICAgICAgcmV2ZXJzZVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIGZsaXBTZXF1ZW5jZTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gbWFwRmFjdG9yeShpdGVyYWJsZSwgbWFwcGVyLCBjb250ZXh0KSB7XG4gICAgdmFyIG1hcHBlZFNlcXVlbmNlID0gbWFrZVNlcXVlbmNlKGl0ZXJhYmxlKTtcbiAgICBtYXBwZWRTZXF1ZW5jZS5zaXplID0gaXRlcmFibGUuc2l6ZTtcbiAgICBtYXBwZWRTZXF1ZW5jZS5oYXMgPSBmdW5jdGlvbihrZXkgKSB7cmV0dXJuIGl0ZXJhYmxlLmhhcyhrZXkpfTtcbiAgICBtYXBwZWRTZXF1ZW5jZS5nZXQgPSBmdW5jdGlvbihrZXksIG5vdFNldFZhbHVlKSAge1xuICAgICAgdmFyIHYgPSBpdGVyYWJsZS5nZXQoa2V5LCBOT1RfU0VUKTtcbiAgICAgIHJldHVybiB2ID09PSBOT1RfU0VUID9cbiAgICAgICAgbm90U2V0VmFsdWUgOlxuICAgICAgICBtYXBwZXIuY2FsbChjb250ZXh0LCB2LCBrZXksIGl0ZXJhYmxlKTtcbiAgICB9O1xuICAgIG1hcHBlZFNlcXVlbmNlLl9faXRlcmF0ZVVuY2FjaGVkID0gZnVuY3Rpb24gKGZuLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICByZXR1cm4gaXRlcmFibGUuX19pdGVyYXRlKFxuICAgICAgICBmdW5jdGlvbih2LCBrLCBjKSAge3JldHVybiBmbihtYXBwZXIuY2FsbChjb250ZXh0LCB2LCBrLCBjKSwgaywgdGhpcyQwKSAhPT0gZmFsc2V9LFxuICAgICAgICByZXZlcnNlXG4gICAgICApO1xuICAgIH1cbiAgICBtYXBwZWRTZXF1ZW5jZS5fX2l0ZXJhdG9yVW5jYWNoZWQgPSBmdW5jdGlvbiAodHlwZSwgcmV2ZXJzZSkge1xuICAgICAgdmFyIGl0ZXJhdG9yID0gaXRlcmFibGUuX19pdGVyYXRvcihJVEVSQVRFX0VOVFJJRVMsIHJldmVyc2UpO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHZhciBzdGVwID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICBpZiAoc3RlcC5kb25lKSB7XG4gICAgICAgICAgcmV0dXJuIHN0ZXA7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGVudHJ5ID0gc3RlcC52YWx1ZTtcbiAgICAgICAgdmFyIGtleSA9IGVudHJ5WzBdO1xuICAgICAgICByZXR1cm4gaXRlcmF0b3JWYWx1ZShcbiAgICAgICAgICB0eXBlLFxuICAgICAgICAgIGtleSxcbiAgICAgICAgICBtYXBwZXIuY2FsbChjb250ZXh0LCBlbnRyeVsxXSwga2V5LCBpdGVyYWJsZSksXG4gICAgICAgICAgc3RlcFxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBtYXBwZWRTZXF1ZW5jZTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gcmV2ZXJzZUZhY3RvcnkoaXRlcmFibGUsIHVzZUtleXMpIHtcbiAgICB2YXIgcmV2ZXJzZWRTZXF1ZW5jZSA9IG1ha2VTZXF1ZW5jZShpdGVyYWJsZSk7XG4gICAgcmV2ZXJzZWRTZXF1ZW5jZS5faXRlciA9IGl0ZXJhYmxlO1xuICAgIHJldmVyc2VkU2VxdWVuY2Uuc2l6ZSA9IGl0ZXJhYmxlLnNpemU7XG4gICAgcmV2ZXJzZWRTZXF1ZW5jZS5yZXZlcnNlID0gZnVuY3Rpb24oKSAge3JldHVybiBpdGVyYWJsZX07XG4gICAgaWYgKGl0ZXJhYmxlLmZsaXApIHtcbiAgICAgIHJldmVyc2VkU2VxdWVuY2UuZmxpcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZsaXBTZXF1ZW5jZSA9IGZsaXBGYWN0b3J5KGl0ZXJhYmxlKTtcbiAgICAgICAgZmxpcFNlcXVlbmNlLnJldmVyc2UgPSBmdW5jdGlvbigpICB7cmV0dXJuIGl0ZXJhYmxlLmZsaXAoKX07XG4gICAgICAgIHJldHVybiBmbGlwU2VxdWVuY2U7XG4gICAgICB9O1xuICAgIH1cbiAgICByZXZlcnNlZFNlcXVlbmNlLmdldCA9IGZ1bmN0aW9uKGtleSwgbm90U2V0VmFsdWUpIFxuICAgICAge3JldHVybiBpdGVyYWJsZS5nZXQodXNlS2V5cyA/IGtleSA6IC0xIC0ga2V5LCBub3RTZXRWYWx1ZSl9O1xuICAgIHJldmVyc2VkU2VxdWVuY2UuaGFzID0gZnVuY3Rpb24oa2V5IClcbiAgICAgIHtyZXR1cm4gaXRlcmFibGUuaGFzKHVzZUtleXMgPyBrZXkgOiAtMSAtIGtleSl9O1xuICAgIHJldmVyc2VkU2VxdWVuY2UuaW5jbHVkZXMgPSBmdW5jdGlvbih2YWx1ZSApIHtyZXR1cm4gaXRlcmFibGUuaW5jbHVkZXModmFsdWUpfTtcbiAgICByZXZlcnNlZFNlcXVlbmNlLmNhY2hlUmVzdWx0ID0gY2FjaGVSZXN1bHRUaHJvdWdoO1xuICAgIHJldmVyc2VkU2VxdWVuY2UuX19pdGVyYXRlID0gZnVuY3Rpb24gKGZuLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICByZXR1cm4gaXRlcmFibGUuX19pdGVyYXRlKGZ1bmN0aW9uKHYsIGspICB7cmV0dXJuIGZuKHYsIGssIHRoaXMkMCl9LCAhcmV2ZXJzZSk7XG4gICAgfTtcbiAgICByZXZlcnNlZFNlcXVlbmNlLl9faXRlcmF0b3IgPVxuICAgICAgZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkgIHtyZXR1cm4gaXRlcmFibGUuX19pdGVyYXRvcih0eXBlLCAhcmV2ZXJzZSl9O1xuICAgIHJldHVybiByZXZlcnNlZFNlcXVlbmNlO1xuICB9XG5cblxuICBmdW5jdGlvbiBmaWx0ZXJGYWN0b3J5KGl0ZXJhYmxlLCBwcmVkaWNhdGUsIGNvbnRleHQsIHVzZUtleXMpIHtcbiAgICB2YXIgZmlsdGVyU2VxdWVuY2UgPSBtYWtlU2VxdWVuY2UoaXRlcmFibGUpO1xuICAgIGlmICh1c2VLZXlzKSB7XG4gICAgICBmaWx0ZXJTZXF1ZW5jZS5oYXMgPSBmdW5jdGlvbihrZXkgKSB7XG4gICAgICAgIHZhciB2ID0gaXRlcmFibGUuZ2V0KGtleSwgTk9UX1NFVCk7XG4gICAgICAgIHJldHVybiB2ICE9PSBOT1RfU0VUICYmICEhcHJlZGljYXRlLmNhbGwoY29udGV4dCwgdiwga2V5LCBpdGVyYWJsZSk7XG4gICAgICB9O1xuICAgICAgZmlsdGVyU2VxdWVuY2UuZ2V0ID0gZnVuY3Rpb24oa2V5LCBub3RTZXRWYWx1ZSkgIHtcbiAgICAgICAgdmFyIHYgPSBpdGVyYWJsZS5nZXQoa2V5LCBOT1RfU0VUKTtcbiAgICAgICAgcmV0dXJuIHYgIT09IE5PVF9TRVQgJiYgcHJlZGljYXRlLmNhbGwoY29udGV4dCwgdiwga2V5LCBpdGVyYWJsZSkgP1xuICAgICAgICAgIHYgOiBub3RTZXRWYWx1ZTtcbiAgICAgIH07XG4gICAgfVxuICAgIGZpbHRlclNlcXVlbmNlLl9faXRlcmF0ZVVuY2FjaGVkID0gZnVuY3Rpb24gKGZuLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICBpdGVyYWJsZS5fX2l0ZXJhdGUoZnVuY3Rpb24odiwgaywgYykgIHtcbiAgICAgICAgaWYgKHByZWRpY2F0ZS5jYWxsKGNvbnRleHQsIHYsIGssIGMpKSB7XG4gICAgICAgICAgaXRlcmF0aW9ucysrO1xuICAgICAgICAgIHJldHVybiBmbih2LCB1c2VLZXlzID8gayA6IGl0ZXJhdGlvbnMgLSAxLCB0aGlzJDApO1xuICAgICAgICB9XG4gICAgICB9LCByZXZlcnNlKTtcbiAgICAgIHJldHVybiBpdGVyYXRpb25zO1xuICAgIH07XG4gICAgZmlsdGVyU2VxdWVuY2UuX19pdGVyYXRvclVuY2FjaGVkID0gZnVuY3Rpb24gKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIHZhciBpdGVyYXRvciA9IGl0ZXJhYmxlLl9faXRlcmF0b3IoSVRFUkFURV9FTlRSSUVTLCByZXZlcnNlKTtcbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSAge1xuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgIHZhciBzdGVwID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICAgIGlmIChzdGVwLmRvbmUpIHtcbiAgICAgICAgICAgIHJldHVybiBzdGVwO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YXIgZW50cnkgPSBzdGVwLnZhbHVlO1xuICAgICAgICAgIHZhciBrZXkgPSBlbnRyeVswXTtcbiAgICAgICAgICB2YXIgdmFsdWUgPSBlbnRyeVsxXTtcbiAgICAgICAgICBpZiAocHJlZGljYXRlLmNhbGwoY29udGV4dCwgdmFsdWUsIGtleSwgaXRlcmFibGUpKSB7XG4gICAgICAgICAgICByZXR1cm4gaXRlcmF0b3JWYWx1ZSh0eXBlLCB1c2VLZXlzID8ga2V5IDogaXRlcmF0aW9ucysrLCB2YWx1ZSwgc3RlcCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGZpbHRlclNlcXVlbmNlO1xuICB9XG5cblxuICBmdW5jdGlvbiBjb3VudEJ5RmFjdG9yeShpdGVyYWJsZSwgZ3JvdXBlciwgY29udGV4dCkge1xuICAgIHZhciBncm91cHMgPSBNYXAoKS5hc011dGFibGUoKTtcbiAgICBpdGVyYWJsZS5fX2l0ZXJhdGUoZnVuY3Rpb24odiwgaykgIHtcbiAgICAgIGdyb3Vwcy51cGRhdGUoXG4gICAgICAgIGdyb3VwZXIuY2FsbChjb250ZXh0LCB2LCBrLCBpdGVyYWJsZSksXG4gICAgICAgIDAsXG4gICAgICAgIGZ1bmN0aW9uKGEgKSB7cmV0dXJuIGEgKyAxfVxuICAgICAgKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZ3JvdXBzLmFzSW1tdXRhYmxlKCk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIGdyb3VwQnlGYWN0b3J5KGl0ZXJhYmxlLCBncm91cGVyLCBjb250ZXh0KSB7XG4gICAgdmFyIGlzS2V5ZWRJdGVyID0gaXNLZXllZChpdGVyYWJsZSk7XG4gICAgdmFyIGdyb3VwcyA9IChpc09yZGVyZWQoaXRlcmFibGUpID8gT3JkZXJlZE1hcCgpIDogTWFwKCkpLmFzTXV0YWJsZSgpO1xuICAgIGl0ZXJhYmxlLl9faXRlcmF0ZShmdW5jdGlvbih2LCBrKSAge1xuICAgICAgZ3JvdXBzLnVwZGF0ZShcbiAgICAgICAgZ3JvdXBlci5jYWxsKGNvbnRleHQsIHYsIGssIGl0ZXJhYmxlKSxcbiAgICAgICAgZnVuY3Rpb24oYSApIHtyZXR1cm4gKGEgPSBhIHx8IFtdLCBhLnB1c2goaXNLZXllZEl0ZXIgPyBbaywgdl0gOiB2KSwgYSl9XG4gICAgICApO1xuICAgIH0pO1xuICAgIHZhciBjb2VyY2UgPSBpdGVyYWJsZUNsYXNzKGl0ZXJhYmxlKTtcbiAgICByZXR1cm4gZ3JvdXBzLm1hcChmdW5jdGlvbihhcnIgKSB7cmV0dXJuIHJlaWZ5KGl0ZXJhYmxlLCBjb2VyY2UoYXJyKSl9KTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gc2xpY2VGYWN0b3J5KGl0ZXJhYmxlLCBiZWdpbiwgZW5kLCB1c2VLZXlzKSB7XG4gICAgdmFyIG9yaWdpbmFsU2l6ZSA9IGl0ZXJhYmxlLnNpemU7XG5cbiAgICAvLyBTYW5pdGl6ZSBiZWdpbiAmIGVuZCB1c2luZyB0aGlzIHNob3J0aGFuZCBmb3IgVG9JbnQzMihhcmd1bWVudClcbiAgICAvLyBodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtdG9pbnQzMlxuICAgIGlmIChiZWdpbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBiZWdpbiA9IGJlZ2luIHwgMDtcbiAgICB9XG4gICAgaWYgKGVuZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBlbmQgPSBlbmQgfCAwO1xuICAgIH1cblxuICAgIGlmICh3aG9sZVNsaWNlKGJlZ2luLCBlbmQsIG9yaWdpbmFsU2l6ZSkpIHtcbiAgICAgIHJldHVybiBpdGVyYWJsZTtcbiAgICB9XG5cbiAgICB2YXIgcmVzb2x2ZWRCZWdpbiA9IHJlc29sdmVCZWdpbihiZWdpbiwgb3JpZ2luYWxTaXplKTtcbiAgICB2YXIgcmVzb2x2ZWRFbmQgPSByZXNvbHZlRW5kKGVuZCwgb3JpZ2luYWxTaXplKTtcblxuICAgIC8vIGJlZ2luIG9yIGVuZCB3aWxsIGJlIE5hTiBpZiB0aGV5IHdlcmUgcHJvdmlkZWQgYXMgbmVnYXRpdmUgbnVtYmVycyBhbmRcbiAgICAvLyB0aGlzIGl0ZXJhYmxlJ3Mgc2l6ZSBpcyB1bmtub3duLiBJbiB0aGF0IGNhc2UsIGNhY2hlIGZpcnN0IHNvIHRoZXJlIGlzXG4gICAgLy8gYSBrbm93biBzaXplIGFuZCB0aGVzZSBkbyBub3QgcmVzb2x2ZSB0byBOYU4uXG4gICAgaWYgKHJlc29sdmVkQmVnaW4gIT09IHJlc29sdmVkQmVnaW4gfHwgcmVzb2x2ZWRFbmQgIT09IHJlc29sdmVkRW5kKSB7XG4gICAgICByZXR1cm4gc2xpY2VGYWN0b3J5KGl0ZXJhYmxlLnRvU2VxKCkuY2FjaGVSZXN1bHQoKSwgYmVnaW4sIGVuZCwgdXNlS2V5cyk7XG4gICAgfVxuXG4gICAgLy8gTm90ZTogcmVzb2x2ZWRFbmQgaXMgdW5kZWZpbmVkIHdoZW4gdGhlIG9yaWdpbmFsIHNlcXVlbmNlJ3MgbGVuZ3RoIGlzXG4gICAgLy8gdW5rbm93biBhbmQgdGhpcyBzbGljZSBkaWQgbm90IHN1cHBseSBhbiBlbmQgYW5kIHNob3VsZCBjb250YWluIGFsbFxuICAgIC8vIGVsZW1lbnRzIGFmdGVyIHJlc29sdmVkQmVnaW4uXG4gICAgLy8gSW4gdGhhdCBjYXNlLCByZXNvbHZlZFNpemUgd2lsbCBiZSBOYU4gYW5kIHNsaWNlU2l6ZSB3aWxsIHJlbWFpbiB1bmRlZmluZWQuXG4gICAgdmFyIHJlc29sdmVkU2l6ZSA9IHJlc29sdmVkRW5kIC0gcmVzb2x2ZWRCZWdpbjtcbiAgICB2YXIgc2xpY2VTaXplO1xuICAgIGlmIChyZXNvbHZlZFNpemUgPT09IHJlc29sdmVkU2l6ZSkge1xuICAgICAgc2xpY2VTaXplID0gcmVzb2x2ZWRTaXplIDwgMCA/IDAgOiByZXNvbHZlZFNpemU7XG4gICAgfVxuXG4gICAgdmFyIHNsaWNlU2VxID0gbWFrZVNlcXVlbmNlKGl0ZXJhYmxlKTtcblxuICAgIC8vIElmIGl0ZXJhYmxlLnNpemUgaXMgdW5kZWZpbmVkLCB0aGUgc2l6ZSBvZiB0aGUgcmVhbGl6ZWQgc2xpY2VTZXEgaXNcbiAgICAvLyB1bmtub3duIGF0IHRoaXMgcG9pbnQgdW5sZXNzIHRoZSBudW1iZXIgb2YgaXRlbXMgdG8gc2xpY2UgaXMgMFxuICAgIHNsaWNlU2VxLnNpemUgPSBzbGljZVNpemUgPT09IDAgPyBzbGljZVNpemUgOiBpdGVyYWJsZS5zaXplICYmIHNsaWNlU2l6ZSB8fCB1bmRlZmluZWQ7XG5cbiAgICBpZiAoIXVzZUtleXMgJiYgaXNTZXEoaXRlcmFibGUpICYmIHNsaWNlU2l6ZSA+PSAwKSB7XG4gICAgICBzbGljZVNlcS5nZXQgPSBmdW5jdGlvbiAoaW5kZXgsIG5vdFNldFZhbHVlKSB7XG4gICAgICAgIGluZGV4ID0gd3JhcEluZGV4KHRoaXMsIGluZGV4KTtcbiAgICAgICAgcmV0dXJuIGluZGV4ID49IDAgJiYgaW5kZXggPCBzbGljZVNpemUgP1xuICAgICAgICAgIGl0ZXJhYmxlLmdldChpbmRleCArIHJlc29sdmVkQmVnaW4sIG5vdFNldFZhbHVlKSA6XG4gICAgICAgICAgbm90U2V0VmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc2xpY2VTZXEuX19pdGVyYXRlVW5jYWNoZWQgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgaWYgKHNsaWNlU2l6ZSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlUmVzdWx0KCkuX19pdGVyYXRlKGZuLCByZXZlcnNlKTtcbiAgICAgIH1cbiAgICAgIHZhciBza2lwcGVkID0gMDtcbiAgICAgIHZhciBpc1NraXBwaW5nID0gdHJ1ZTtcbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIGl0ZXJhYmxlLl9faXRlcmF0ZShmdW5jdGlvbih2LCBrKSAge1xuICAgICAgICBpZiAoIShpc1NraXBwaW5nICYmIChpc1NraXBwaW5nID0gc2tpcHBlZCsrIDwgcmVzb2x2ZWRCZWdpbikpKSB7XG4gICAgICAgICAgaXRlcmF0aW9ucysrO1xuICAgICAgICAgIHJldHVybiBmbih2LCB1c2VLZXlzID8gayA6IGl0ZXJhdGlvbnMgLSAxLCB0aGlzJDApICE9PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICBpdGVyYXRpb25zICE9PSBzbGljZVNpemU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGl0ZXJhdGlvbnM7XG4gICAgfTtcblxuICAgIHNsaWNlU2VxLl9faXRlcmF0b3JVbmNhY2hlZCA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIGlmIChzbGljZVNpemUgIT09IDAgJiYgcmV2ZXJzZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZVJlc3VsdCgpLl9faXRlcmF0b3IodHlwZSwgcmV2ZXJzZSk7XG4gICAgICB9XG4gICAgICAvLyBEb24ndCBib3RoZXIgaW5zdGFudGlhdGluZyBwYXJlbnQgaXRlcmF0b3IgaWYgdGFraW5nIDAuXG4gICAgICB2YXIgaXRlcmF0b3IgPSBzbGljZVNpemUgIT09IDAgJiYgaXRlcmFibGUuX19pdGVyYXRvcih0eXBlLCByZXZlcnNlKTtcbiAgICAgIHZhciBza2lwcGVkID0gMDtcbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSAge1xuICAgICAgICB3aGlsZSAoc2tpcHBlZCsrIDwgcmVzb2x2ZWRCZWdpbikge1xuICAgICAgICAgIGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoKytpdGVyYXRpb25zID4gc2xpY2VTaXplKSB7XG4gICAgICAgICAgcmV0dXJuIGl0ZXJhdG9yRG9uZSgpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzdGVwID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICBpZiAodXNlS2V5cyB8fCB0eXBlID09PSBJVEVSQVRFX1ZBTFVFUykge1xuICAgICAgICAgIHJldHVybiBzdGVwO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09IElURVJBVEVfS0VZUykge1xuICAgICAgICAgIHJldHVybiBpdGVyYXRvclZhbHVlKHR5cGUsIGl0ZXJhdGlvbnMgLSAxLCB1bmRlZmluZWQsIHN0ZXApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBpdGVyYXRvclZhbHVlKHR5cGUsIGl0ZXJhdGlvbnMgLSAxLCBzdGVwLnZhbHVlWzFdLCBzdGVwKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNsaWNlU2VxO1xuICB9XG5cblxuICBmdW5jdGlvbiB0YWtlV2hpbGVGYWN0b3J5KGl0ZXJhYmxlLCBwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICB2YXIgdGFrZVNlcXVlbmNlID0gbWFrZVNlcXVlbmNlKGl0ZXJhYmxlKTtcbiAgICB0YWtlU2VxdWVuY2UuX19pdGVyYXRlVW5jYWNoZWQgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgaWYgKHJldmVyc2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FjaGVSZXN1bHQoKS5fX2l0ZXJhdGUoZm4sIHJldmVyc2UpO1xuICAgICAgfVxuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgaXRlcmFibGUuX19pdGVyYXRlKGZ1bmN0aW9uKHYsIGssIGMpIFxuICAgICAgICB7cmV0dXJuIHByZWRpY2F0ZS5jYWxsKGNvbnRleHQsIHYsIGssIGMpICYmICsraXRlcmF0aW9ucyAmJiBmbih2LCBrLCB0aGlzJDApfVxuICAgICAgKTtcbiAgICAgIHJldHVybiBpdGVyYXRpb25zO1xuICAgIH07XG4gICAgdGFrZVNlcXVlbmNlLl9faXRlcmF0b3JVbmNhY2hlZCA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlUmVzdWx0KCkuX19pdGVyYXRvcih0eXBlLCByZXZlcnNlKTtcbiAgICAgIH1cbiAgICAgIHZhciBpdGVyYXRvciA9IGl0ZXJhYmxlLl9faXRlcmF0b3IoSVRFUkFURV9FTlRSSUVTLCByZXZlcnNlKTtcbiAgICAgIHZhciBpdGVyYXRpbmcgPSB0cnVlO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIGlmICghaXRlcmF0aW5nKSB7XG4gICAgICAgICAgcmV0dXJuIGl0ZXJhdG9yRG9uZSgpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzdGVwID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICBpZiAoc3RlcC5kb25lKSB7XG4gICAgICAgICAgcmV0dXJuIHN0ZXA7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGVudHJ5ID0gc3RlcC52YWx1ZTtcbiAgICAgICAgdmFyIGsgPSBlbnRyeVswXTtcbiAgICAgICAgdmFyIHYgPSBlbnRyeVsxXTtcbiAgICAgICAgaWYgKCFwcmVkaWNhdGUuY2FsbChjb250ZXh0LCB2LCBrLCB0aGlzJDApKSB7XG4gICAgICAgICAgaXRlcmF0aW5nID0gZmFsc2U7XG4gICAgICAgICAgcmV0dXJuIGl0ZXJhdG9yRG9uZSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0eXBlID09PSBJVEVSQVRFX0VOVFJJRVMgPyBzdGVwIDpcbiAgICAgICAgICBpdGVyYXRvclZhbHVlKHR5cGUsIGssIHYsIHN0ZXApO1xuICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gdGFrZVNlcXVlbmNlO1xuICB9XG5cblxuICBmdW5jdGlvbiBza2lwV2hpbGVGYWN0b3J5KGl0ZXJhYmxlLCBwcmVkaWNhdGUsIGNvbnRleHQsIHVzZUtleXMpIHtcbiAgICB2YXIgc2tpcFNlcXVlbmNlID0gbWFrZVNlcXVlbmNlKGl0ZXJhYmxlKTtcbiAgICBza2lwU2VxdWVuY2UuX19pdGVyYXRlVW5jYWNoZWQgPSBmdW5jdGlvbiAoZm4sIHJldmVyc2UpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlUmVzdWx0KCkuX19pdGVyYXRlKGZuLCByZXZlcnNlKTtcbiAgICAgIH1cbiAgICAgIHZhciBpc1NraXBwaW5nID0gdHJ1ZTtcbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIGl0ZXJhYmxlLl9faXRlcmF0ZShmdW5jdGlvbih2LCBrLCBjKSAge1xuICAgICAgICBpZiAoIShpc1NraXBwaW5nICYmIChpc1NraXBwaW5nID0gcHJlZGljYXRlLmNhbGwoY29udGV4dCwgdiwgaywgYykpKSkge1xuICAgICAgICAgIGl0ZXJhdGlvbnMrKztcbiAgICAgICAgICByZXR1cm4gZm4odiwgdXNlS2V5cyA/IGsgOiBpdGVyYXRpb25zIC0gMSwgdGhpcyQwKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gaXRlcmF0aW9ucztcbiAgICB9O1xuICAgIHNraXBTZXF1ZW5jZS5fX2l0ZXJhdG9yVW5jYWNoZWQgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZVJlc3VsdCgpLl9faXRlcmF0b3IodHlwZSwgcmV2ZXJzZSk7XG4gICAgICB9XG4gICAgICB2YXIgaXRlcmF0b3IgPSBpdGVyYWJsZS5fX2l0ZXJhdG9yKElURVJBVEVfRU5UUklFUywgcmV2ZXJzZSk7XG4gICAgICB2YXIgc2tpcHBpbmcgPSB0cnVlO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIHZhciBzdGVwLCBrLCB2O1xuICAgICAgICBkbyB7XG4gICAgICAgICAgc3RlcCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgICBpZiAoc3RlcC5kb25lKSB7XG4gICAgICAgICAgICBpZiAodXNlS2V5cyB8fCB0eXBlID09PSBJVEVSQVRFX1ZBTFVFUykge1xuICAgICAgICAgICAgICByZXR1cm4gc3RlcDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gSVRFUkFURV9LRVlTKSB7XG4gICAgICAgICAgICAgIHJldHVybiBpdGVyYXRvclZhbHVlKHR5cGUsIGl0ZXJhdGlvbnMrKywgdW5kZWZpbmVkLCBzdGVwKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBpdGVyYXRvclZhbHVlKHR5cGUsIGl0ZXJhdGlvbnMrKywgc3RlcC52YWx1ZVsxXSwgc3RlcCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhciBlbnRyeSA9IHN0ZXAudmFsdWU7XG4gICAgICAgICAgayA9IGVudHJ5WzBdO1xuICAgICAgICAgIHYgPSBlbnRyeVsxXTtcbiAgICAgICAgICBza2lwcGluZyAmJiAoc2tpcHBpbmcgPSBwcmVkaWNhdGUuY2FsbChjb250ZXh0LCB2LCBrLCB0aGlzJDApKTtcbiAgICAgICAgfSB3aGlsZSAoc2tpcHBpbmcpO1xuICAgICAgICByZXR1cm4gdHlwZSA9PT0gSVRFUkFURV9FTlRSSUVTID8gc3RlcCA6XG4gICAgICAgICAgaXRlcmF0b3JWYWx1ZSh0eXBlLCBrLCB2LCBzdGVwKTtcbiAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIHNraXBTZXF1ZW5jZTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gY29uY2F0RmFjdG9yeShpdGVyYWJsZSwgdmFsdWVzKSB7XG4gICAgdmFyIGlzS2V5ZWRJdGVyYWJsZSA9IGlzS2V5ZWQoaXRlcmFibGUpO1xuICAgIHZhciBpdGVycyA9IFtpdGVyYWJsZV0uY29uY2F0KHZhbHVlcykubWFwKGZ1bmN0aW9uKHYgKSB7XG4gICAgICBpZiAoIWlzSXRlcmFibGUodikpIHtcbiAgICAgICAgdiA9IGlzS2V5ZWRJdGVyYWJsZSA/XG4gICAgICAgICAga2V5ZWRTZXFGcm9tVmFsdWUodikgOlxuICAgICAgICAgIGluZGV4ZWRTZXFGcm9tVmFsdWUoQXJyYXkuaXNBcnJheSh2KSA/IHYgOiBbdl0pO1xuICAgICAgfSBlbHNlIGlmIChpc0tleWVkSXRlcmFibGUpIHtcbiAgICAgICAgdiA9IEtleWVkSXRlcmFibGUodik7XG4gICAgICB9XG4gICAgICByZXR1cm4gdjtcbiAgICB9KS5maWx0ZXIoZnVuY3Rpb24odiApIHtyZXR1cm4gdi5zaXplICE9PSAwfSk7XG5cbiAgICBpZiAoaXRlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gaXRlcmFibGU7XG4gICAgfVxuXG4gICAgaWYgKGl0ZXJzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdmFyIHNpbmdsZXRvbiA9IGl0ZXJzWzBdO1xuICAgICAgaWYgKHNpbmdsZXRvbiA9PT0gaXRlcmFibGUgfHxcbiAgICAgICAgICBpc0tleWVkSXRlcmFibGUgJiYgaXNLZXllZChzaW5nbGV0b24pIHx8XG4gICAgICAgICAgaXNJbmRleGVkKGl0ZXJhYmxlKSAmJiBpc0luZGV4ZWQoc2luZ2xldG9uKSkge1xuICAgICAgICByZXR1cm4gc2luZ2xldG9uO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBjb25jYXRTZXEgPSBuZXcgQXJyYXlTZXEoaXRlcnMpO1xuICAgIGlmIChpc0tleWVkSXRlcmFibGUpIHtcbiAgICAgIGNvbmNhdFNlcSA9IGNvbmNhdFNlcS50b0tleWVkU2VxKCk7XG4gICAgfSBlbHNlIGlmICghaXNJbmRleGVkKGl0ZXJhYmxlKSkge1xuICAgICAgY29uY2F0U2VxID0gY29uY2F0U2VxLnRvU2V0U2VxKCk7XG4gICAgfVxuICAgIGNvbmNhdFNlcSA9IGNvbmNhdFNlcS5mbGF0dGVuKHRydWUpO1xuICAgIGNvbmNhdFNlcS5zaXplID0gaXRlcnMucmVkdWNlKFxuICAgICAgZnVuY3Rpb24oc3VtLCBzZXEpICB7XG4gICAgICAgIGlmIChzdW0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHZhciBzaXplID0gc2VxLnNpemU7XG4gICAgICAgICAgaWYgKHNpemUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHN1bSArIHNpemU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgMFxuICAgICk7XG4gICAgcmV0dXJuIGNvbmNhdFNlcTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gZmxhdHRlbkZhY3RvcnkoaXRlcmFibGUsIGRlcHRoLCB1c2VLZXlzKSB7XG4gICAgdmFyIGZsYXRTZXF1ZW5jZSA9IG1ha2VTZXF1ZW5jZShpdGVyYWJsZSk7XG4gICAgZmxhdFNlcXVlbmNlLl9faXRlcmF0ZVVuY2FjaGVkID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHtcbiAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgIHZhciBzdG9wcGVkID0gZmFsc2U7XG4gICAgICBmdW5jdGlvbiBmbGF0RGVlcChpdGVyLCBjdXJyZW50RGVwdGgpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgICAgaXRlci5fX2l0ZXJhdGUoZnVuY3Rpb24odiwgaykgIHtcbiAgICAgICAgICBpZiAoKCFkZXB0aCB8fCBjdXJyZW50RGVwdGggPCBkZXB0aCkgJiYgaXNJdGVyYWJsZSh2KSkge1xuICAgICAgICAgICAgZmxhdERlZXAodiwgY3VycmVudERlcHRoICsgMSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChmbih2LCB1c2VLZXlzID8gayA6IGl0ZXJhdGlvbnMrKywgdGhpcyQwKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHN0b3BwZWQgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gIXN0b3BwZWQ7XG4gICAgICAgIH0sIHJldmVyc2UpO1xuICAgICAgfVxuICAgICAgZmxhdERlZXAoaXRlcmFibGUsIDApO1xuICAgICAgcmV0dXJuIGl0ZXJhdGlvbnM7XG4gICAgfVxuICAgIGZsYXRTZXF1ZW5jZS5fX2l0ZXJhdG9yVW5jYWNoZWQgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICB2YXIgaXRlcmF0b3IgPSBpdGVyYWJsZS5fX2l0ZXJhdG9yKHR5cGUsIHJldmVyc2UpO1xuICAgICAgdmFyIHN0YWNrID0gW107XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgd2hpbGUgKGl0ZXJhdG9yKSB7XG4gICAgICAgICAgdmFyIHN0ZXAgPSBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgICAgaWYgKHN0ZXAuZG9uZSAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yID0gc3RhY2sucG9wKCk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIHYgPSBzdGVwLnZhbHVlO1xuICAgICAgICAgIGlmICh0eXBlID09PSBJVEVSQVRFX0VOVFJJRVMpIHtcbiAgICAgICAgICAgIHYgPSB2WzFdO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoKCFkZXB0aCB8fCBzdGFjay5sZW5ndGggPCBkZXB0aCkgJiYgaXNJdGVyYWJsZSh2KSkge1xuICAgICAgICAgICAgc3RhY2sucHVzaChpdGVyYXRvcik7XG4gICAgICAgICAgICBpdGVyYXRvciA9IHYuX19pdGVyYXRvcih0eXBlLCByZXZlcnNlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVzZUtleXMgPyBzdGVwIDogaXRlcmF0b3JWYWx1ZSh0eXBlLCBpdGVyYXRpb25zKyssIHYsIHN0ZXApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXRlcmF0b3JEb25lKCk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGZsYXRTZXF1ZW5jZTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gZmxhdE1hcEZhY3RvcnkoaXRlcmFibGUsIG1hcHBlciwgY29udGV4dCkge1xuICAgIHZhciBjb2VyY2UgPSBpdGVyYWJsZUNsYXNzKGl0ZXJhYmxlKTtcbiAgICByZXR1cm4gaXRlcmFibGUudG9TZXEoKS5tYXAoXG4gICAgICBmdW5jdGlvbih2LCBrKSAge3JldHVybiBjb2VyY2UobWFwcGVyLmNhbGwoY29udGV4dCwgdiwgaywgaXRlcmFibGUpKX1cbiAgICApLmZsYXR0ZW4odHJ1ZSk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIGludGVycG9zZUZhY3RvcnkoaXRlcmFibGUsIHNlcGFyYXRvcikge1xuICAgIHZhciBpbnRlcnBvc2VkU2VxdWVuY2UgPSBtYWtlU2VxdWVuY2UoaXRlcmFibGUpO1xuICAgIGludGVycG9zZWRTZXF1ZW5jZS5zaXplID0gaXRlcmFibGUuc2l6ZSAmJiBpdGVyYWJsZS5zaXplICogMiAtMTtcbiAgICBpbnRlcnBvc2VkU2VxdWVuY2UuX19pdGVyYXRlVW5jYWNoZWQgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgaXRlcmFibGUuX19pdGVyYXRlKGZ1bmN0aW9uKHYsIGspIFxuICAgICAgICB7cmV0dXJuICghaXRlcmF0aW9ucyB8fCBmbihzZXBhcmF0b3IsIGl0ZXJhdGlvbnMrKywgdGhpcyQwKSAhPT0gZmFsc2UpICYmXG4gICAgICAgIGZuKHYsIGl0ZXJhdGlvbnMrKywgdGhpcyQwKSAhPT0gZmFsc2V9LFxuICAgICAgICByZXZlcnNlXG4gICAgICApO1xuICAgICAgcmV0dXJuIGl0ZXJhdGlvbnM7XG4gICAgfTtcbiAgICBpbnRlcnBvc2VkU2VxdWVuY2UuX19pdGVyYXRvclVuY2FjaGVkID0gZnVuY3Rpb24odHlwZSwgcmV2ZXJzZSkge1xuICAgICAgdmFyIGl0ZXJhdG9yID0gaXRlcmFibGUuX19pdGVyYXRvcihJVEVSQVRFX1ZBTFVFUywgcmV2ZXJzZSk7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICB2YXIgc3RlcDtcbiAgICAgIHJldHVybiBuZXcgSXRlcmF0b3IoZnVuY3Rpb24oKSAge1xuICAgICAgICBpZiAoIXN0ZXAgfHwgaXRlcmF0aW9ucyAlIDIpIHtcbiAgICAgICAgICBzdGVwID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICAgIGlmIChzdGVwLmRvbmUpIHtcbiAgICAgICAgICAgIHJldHVybiBzdGVwO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXRlcmF0aW9ucyAlIDIgP1xuICAgICAgICAgIGl0ZXJhdG9yVmFsdWUodHlwZSwgaXRlcmF0aW9ucysrLCBzZXBhcmF0b3IpIDpcbiAgICAgICAgICBpdGVyYXRvclZhbHVlKHR5cGUsIGl0ZXJhdGlvbnMrKywgc3RlcC52YWx1ZSwgc3RlcCk7XG4gICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBpbnRlcnBvc2VkU2VxdWVuY2U7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIHNvcnRGYWN0b3J5KGl0ZXJhYmxlLCBjb21wYXJhdG9yLCBtYXBwZXIpIHtcbiAgICBpZiAoIWNvbXBhcmF0b3IpIHtcbiAgICAgIGNvbXBhcmF0b3IgPSBkZWZhdWx0Q29tcGFyYXRvcjtcbiAgICB9XG4gICAgdmFyIGlzS2V5ZWRJdGVyYWJsZSA9IGlzS2V5ZWQoaXRlcmFibGUpO1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgdmFyIGVudHJpZXMgPSBpdGVyYWJsZS50b1NlcSgpLm1hcChcbiAgICAgIGZ1bmN0aW9uKHYsIGspICB7cmV0dXJuIFtrLCB2LCBpbmRleCsrLCBtYXBwZXIgPyBtYXBwZXIodiwgaywgaXRlcmFibGUpIDogdl19XG4gICAgKS50b0FycmF5KCk7XG4gICAgZW50cmllcy5zb3J0KGZ1bmN0aW9uKGEsIGIpICB7cmV0dXJuIGNvbXBhcmF0b3IoYVszXSwgYlszXSkgfHwgYVsyXSAtIGJbMl19KS5mb3JFYWNoKFxuICAgICAgaXNLZXllZEl0ZXJhYmxlID9cbiAgICAgIGZ1bmN0aW9uKHYsIGkpICB7IGVudHJpZXNbaV0ubGVuZ3RoID0gMjsgfSA6XG4gICAgICBmdW5jdGlvbih2LCBpKSAgeyBlbnRyaWVzW2ldID0gdlsxXTsgfVxuICAgICk7XG4gICAgcmV0dXJuIGlzS2V5ZWRJdGVyYWJsZSA/IEtleWVkU2VxKGVudHJpZXMpIDpcbiAgICAgIGlzSW5kZXhlZChpdGVyYWJsZSkgPyBJbmRleGVkU2VxKGVudHJpZXMpIDpcbiAgICAgIFNldFNlcShlbnRyaWVzKTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gbWF4RmFjdG9yeShpdGVyYWJsZSwgY29tcGFyYXRvciwgbWFwcGVyKSB7XG4gICAgaWYgKCFjb21wYXJhdG9yKSB7XG4gICAgICBjb21wYXJhdG9yID0gZGVmYXVsdENvbXBhcmF0b3I7XG4gICAgfVxuICAgIGlmIChtYXBwZXIpIHtcbiAgICAgIHZhciBlbnRyeSA9IGl0ZXJhYmxlLnRvU2VxKClcbiAgICAgICAgLm1hcChmdW5jdGlvbih2LCBrKSAge3JldHVybiBbdiwgbWFwcGVyKHYsIGssIGl0ZXJhYmxlKV19KVxuICAgICAgICAucmVkdWNlKGZ1bmN0aW9uKGEsIGIpICB7cmV0dXJuIG1heENvbXBhcmUoY29tcGFyYXRvciwgYVsxXSwgYlsxXSkgPyBiIDogYX0pO1xuICAgICAgcmV0dXJuIGVudHJ5ICYmIGVudHJ5WzBdO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gaXRlcmFibGUucmVkdWNlKGZ1bmN0aW9uKGEsIGIpICB7cmV0dXJuIG1heENvbXBhcmUoY29tcGFyYXRvciwgYSwgYikgPyBiIDogYX0pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG1heENvbXBhcmUoY29tcGFyYXRvciwgYSwgYikge1xuICAgIHZhciBjb21wID0gY29tcGFyYXRvcihiLCBhKTtcbiAgICAvLyBiIGlzIGNvbnNpZGVyZWQgdGhlIG5ldyBtYXggaWYgdGhlIGNvbXBhcmF0b3IgZGVjbGFyZXMgdGhlbSBlcXVhbCwgYnV0XG4gICAgLy8gdGhleSBhcmUgbm90IGVxdWFsIGFuZCBiIGlzIGluIGZhY3QgYSBudWxsaXNoIHZhbHVlLlxuICAgIHJldHVybiAoY29tcCA9PT0gMCAmJiBiICE9PSBhICYmIChiID09PSB1bmRlZmluZWQgfHwgYiA9PT0gbnVsbCB8fCBiICE9PSBiKSkgfHwgY29tcCA+IDA7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIHppcFdpdGhGYWN0b3J5KGtleUl0ZXIsIHppcHBlciwgaXRlcnMpIHtcbiAgICB2YXIgemlwU2VxdWVuY2UgPSBtYWtlU2VxdWVuY2Uoa2V5SXRlcik7XG4gICAgemlwU2VxdWVuY2Uuc2l6ZSA9IG5ldyBBcnJheVNlcShpdGVycykubWFwKGZ1bmN0aW9uKGkgKSB7cmV0dXJuIGkuc2l6ZX0pLm1pbigpO1xuICAgIC8vIE5vdGU6IHRoaXMgYSBnZW5lcmljIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgX19pdGVyYXRlIGluIHRlcm1zIG9mXG4gICAgLy8gX19pdGVyYXRvciB3aGljaCBtYXkgYmUgbW9yZSBnZW5lcmljYWxseSB1c2VmdWwgaW4gdGhlIGZ1dHVyZS5cbiAgICB6aXBTZXF1ZW5jZS5fX2l0ZXJhdGUgPSBmdW5jdGlvbihmbiwgcmV2ZXJzZSkge1xuICAgICAgLyogZ2VuZXJpYzpcbiAgICAgIHZhciBpdGVyYXRvciA9IHRoaXMuX19pdGVyYXRvcihJVEVSQVRFX0VOVFJJRVMsIHJldmVyc2UpO1xuICAgICAgdmFyIHN0ZXA7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICB3aGlsZSAoIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lKSB7XG4gICAgICAgIGl0ZXJhdGlvbnMrKztcbiAgICAgICAgaWYgKGZuKHN0ZXAudmFsdWVbMV0sIHN0ZXAudmFsdWVbMF0sIHRoaXMpID09PSBmYWxzZSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gaXRlcmF0aW9ucztcbiAgICAgICovXG4gICAgICAvLyBpbmRleGVkOlxuICAgICAgdmFyIGl0ZXJhdG9yID0gdGhpcy5fX2l0ZXJhdG9yKElURVJBVEVfVkFMVUVTLCByZXZlcnNlKTtcbiAgICAgIHZhciBzdGVwO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgd2hpbGUgKCEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZSkge1xuICAgICAgICBpZiAoZm4oc3RlcC52YWx1ZSwgaXRlcmF0aW9ucysrLCB0aGlzKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGl0ZXJhdGlvbnM7XG4gICAgfTtcbiAgICB6aXBTZXF1ZW5jZS5fX2l0ZXJhdG9yVW5jYWNoZWQgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7XG4gICAgICB2YXIgaXRlcmF0b3JzID0gaXRlcnMubWFwKGZ1bmN0aW9uKGkgKVxuICAgICAgICB7cmV0dXJuIChpID0gSXRlcmFibGUoaSksIGdldEl0ZXJhdG9yKHJldmVyc2UgPyBpLnJldmVyc2UoKSA6IGkpKX1cbiAgICAgICk7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICB2YXIgaXNEb25lID0gZmFsc2U7XG4gICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yKGZ1bmN0aW9uKCkgIHtcbiAgICAgICAgdmFyIHN0ZXBzO1xuICAgICAgICBpZiAoIWlzRG9uZSkge1xuICAgICAgICAgIHN0ZXBzID0gaXRlcmF0b3JzLm1hcChmdW5jdGlvbihpICkge3JldHVybiBpLm5leHQoKX0pO1xuICAgICAgICAgIGlzRG9uZSA9IHN0ZXBzLnNvbWUoZnVuY3Rpb24ocyApIHtyZXR1cm4gcy5kb25lfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzRG9uZSkge1xuICAgICAgICAgIHJldHVybiBpdGVyYXRvckRvbmUoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXRlcmF0b3JWYWx1ZShcbiAgICAgICAgICB0eXBlLFxuICAgICAgICAgIGl0ZXJhdGlvbnMrKyxcbiAgICAgICAgICB6aXBwZXIuYXBwbHkobnVsbCwgc3RlcHMubWFwKGZ1bmN0aW9uKHMgKSB7cmV0dXJuIHMudmFsdWV9KSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIHppcFNlcXVlbmNlXG4gIH1cblxuXG4gIC8vICNwcmFnbWEgSGVscGVyIEZ1bmN0aW9uc1xuXG4gIGZ1bmN0aW9uIHJlaWZ5KGl0ZXIsIHNlcSkge1xuICAgIHJldHVybiBpc1NlcShpdGVyKSA/IHNlcSA6IGl0ZXIuY29uc3RydWN0b3Ioc2VxKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHZhbGlkYXRlRW50cnkoZW50cnkpIHtcbiAgICBpZiAoZW50cnkgIT09IE9iamVjdChlbnRyeSkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0V4cGVjdGVkIFtLLCBWXSB0dXBsZTogJyArIGVudHJ5KTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZXNvbHZlU2l6ZShpdGVyKSB7XG4gICAgYXNzZXJ0Tm90SW5maW5pdGUoaXRlci5zaXplKTtcbiAgICByZXR1cm4gZW5zdXJlU2l6ZShpdGVyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGl0ZXJhYmxlQ2xhc3MoaXRlcmFibGUpIHtcbiAgICByZXR1cm4gaXNLZXllZChpdGVyYWJsZSkgPyBLZXllZEl0ZXJhYmxlIDpcbiAgICAgIGlzSW5kZXhlZChpdGVyYWJsZSkgPyBJbmRleGVkSXRlcmFibGUgOlxuICAgICAgU2V0SXRlcmFibGU7XG4gIH1cblxuICBmdW5jdGlvbiBtYWtlU2VxdWVuY2UoaXRlcmFibGUpIHtcbiAgICByZXR1cm4gT2JqZWN0LmNyZWF0ZShcbiAgICAgIChcbiAgICAgICAgaXNLZXllZChpdGVyYWJsZSkgPyBLZXllZFNlcSA6XG4gICAgICAgIGlzSW5kZXhlZChpdGVyYWJsZSkgPyBJbmRleGVkU2VxIDpcbiAgICAgICAgU2V0U2VxXG4gICAgICApLnByb3RvdHlwZVxuICAgICk7XG4gIH1cblxuICBmdW5jdGlvbiBjYWNoZVJlc3VsdFRocm91Z2goKSB7XG4gICAgaWYgKHRoaXMuX2l0ZXIuY2FjaGVSZXN1bHQpIHtcbiAgICAgIHRoaXMuX2l0ZXIuY2FjaGVSZXN1bHQoKTtcbiAgICAgIHRoaXMuc2l6ZSA9IHRoaXMuX2l0ZXIuc2l6ZTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gU2VxLnByb3RvdHlwZS5jYWNoZVJlc3VsdC5jYWxsKHRoaXMpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGRlZmF1bHRDb21wYXJhdG9yKGEsIGIpIHtcbiAgICByZXR1cm4gYSA+IGIgPyAxIDogYSA8IGIgPyAtMSA6IDA7XG4gIH1cblxuICBmdW5jdGlvbiBmb3JjZUl0ZXJhdG9yKGtleVBhdGgpIHtcbiAgICB2YXIgaXRlciA9IGdldEl0ZXJhdG9yKGtleVBhdGgpO1xuICAgIGlmICghaXRlcikge1xuICAgICAgLy8gQXJyYXkgbWlnaHQgbm90IGJlIGl0ZXJhYmxlIGluIHRoaXMgZW52aXJvbm1lbnQsIHNvIHdlIG5lZWQgYSBmYWxsYmFja1xuICAgICAgLy8gdG8gb3VyIHdyYXBwZWQgdHlwZS5cbiAgICAgIGlmICghaXNBcnJheUxpa2Uoa2V5UGF0aCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRXhwZWN0ZWQgaXRlcmFibGUgb3IgYXJyYXktbGlrZTogJyArIGtleVBhdGgpO1xuICAgICAgfVxuICAgICAgaXRlciA9IGdldEl0ZXJhdG9yKEl0ZXJhYmxlKGtleVBhdGgpKTtcbiAgICB9XG4gICAgcmV0dXJuIGl0ZXI7XG4gIH1cblxuICBjcmVhdGVDbGFzcyhSZWNvcmQsIEtleWVkQ29sbGVjdGlvbik7XG5cbiAgICBmdW5jdGlvbiBSZWNvcmQoZGVmYXVsdFZhbHVlcywgbmFtZSkge1xuICAgICAgdmFyIGhhc0luaXRpYWxpemVkO1xuXG4gICAgICB2YXIgUmVjb3JkVHlwZSA9IGZ1bmN0aW9uIFJlY29yZCh2YWx1ZXMpIHtcbiAgICAgICAgaWYgKHZhbHVlcyBpbnN0YW5jZW9mIFJlY29yZFR5cGUpIHtcbiAgICAgICAgICByZXR1cm4gdmFsdWVzO1xuICAgICAgICB9XG4gICAgICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBSZWNvcmRUeXBlKSkge1xuICAgICAgICAgIHJldHVybiBuZXcgUmVjb3JkVHlwZSh2YWx1ZXMpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaGFzSW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgICBoYXNJbml0aWFsaXplZCA9IHRydWU7XG4gICAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhkZWZhdWx0VmFsdWVzKTtcbiAgICAgICAgICBzZXRQcm9wcyhSZWNvcmRUeXBlUHJvdG90eXBlLCBrZXlzKTtcbiAgICAgICAgICBSZWNvcmRUeXBlUHJvdG90eXBlLnNpemUgPSBrZXlzLmxlbmd0aDtcbiAgICAgICAgICBSZWNvcmRUeXBlUHJvdG90eXBlLl9uYW1lID0gbmFtZTtcbiAgICAgICAgICBSZWNvcmRUeXBlUHJvdG90eXBlLl9rZXlzID0ga2V5cztcbiAgICAgICAgICBSZWNvcmRUeXBlUHJvdG90eXBlLl9kZWZhdWx0VmFsdWVzID0gZGVmYXVsdFZhbHVlcztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9tYXAgPSBNYXAodmFsdWVzKTtcbiAgICAgIH07XG5cbiAgICAgIHZhciBSZWNvcmRUeXBlUHJvdG90eXBlID0gUmVjb3JkVHlwZS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKFJlY29yZFByb3RvdHlwZSk7XG4gICAgICBSZWNvcmRUeXBlUHJvdG90eXBlLmNvbnN0cnVjdG9yID0gUmVjb3JkVHlwZTtcblxuICAgICAgcmV0dXJuIFJlY29yZFR5cGU7XG4gICAgfVxuXG4gICAgUmVjb3JkLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX190b1N0cmluZyhyZWNvcmROYW1lKHRoaXMpICsgJyB7JywgJ30nKTtcbiAgICB9O1xuXG4gICAgLy8gQHByYWdtYSBBY2Nlc3NcblxuICAgIFJlY29yZC5wcm90b3R5cGUuaGFzID0gZnVuY3Rpb24oaykge1xuICAgICAgcmV0dXJuIHRoaXMuX2RlZmF1bHRWYWx1ZXMuaGFzT3duUHJvcGVydHkoayk7XG4gICAgfTtcblxuICAgIFJlY29yZC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oaywgbm90U2V0VmFsdWUpIHtcbiAgICAgIGlmICghdGhpcy5oYXMoaykpIHtcbiAgICAgICAgcmV0dXJuIG5vdFNldFZhbHVlO1xuICAgICAgfVxuICAgICAgdmFyIGRlZmF1bHRWYWwgPSB0aGlzLl9kZWZhdWx0VmFsdWVzW2tdO1xuICAgICAgcmV0dXJuIHRoaXMuX21hcCA/IHRoaXMuX21hcC5nZXQoaywgZGVmYXVsdFZhbCkgOiBkZWZhdWx0VmFsO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIE1vZGlmaWNhdGlvblxuXG4gICAgUmVjb3JkLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuX19vd25lcklEKSB7XG4gICAgICAgIHRoaXMuX21hcCAmJiB0aGlzLl9tYXAuY2xlYXIoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICB2YXIgUmVjb3JkVHlwZSA9IHRoaXMuY29uc3RydWN0b3I7XG4gICAgICByZXR1cm4gUmVjb3JkVHlwZS5fZW1wdHkgfHwgKFJlY29yZFR5cGUuX2VtcHR5ID0gbWFrZVJlY29yZCh0aGlzLCBlbXB0eU1hcCgpKSk7XG4gICAgfTtcblxuICAgIFJlY29yZC5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24oaywgdikge1xuICAgICAgaWYgKCF0aGlzLmhhcyhrKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBzZXQgdW5rbm93biBrZXkgXCInICsgayArICdcIiBvbiAnICsgcmVjb3JkTmFtZSh0aGlzKSk7XG4gICAgICB9XG4gICAgICB2YXIgbmV3TWFwID0gdGhpcy5fbWFwICYmIHRoaXMuX21hcC5zZXQoaywgdik7XG4gICAgICBpZiAodGhpcy5fX293bmVySUQgfHwgbmV3TWFwID09PSB0aGlzLl9tYXApIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWFrZVJlY29yZCh0aGlzLCBuZXdNYXApO1xuICAgIH07XG5cbiAgICBSZWNvcmQucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uKGspIHtcbiAgICAgIGlmICghdGhpcy5oYXMoaykpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICB2YXIgbmV3TWFwID0gdGhpcy5fbWFwICYmIHRoaXMuX21hcC5yZW1vdmUoayk7XG4gICAgICBpZiAodGhpcy5fX293bmVySUQgfHwgbmV3TWFwID09PSB0aGlzLl9tYXApIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWFrZVJlY29yZCh0aGlzLCBuZXdNYXApO1xuICAgIH07XG5cbiAgICBSZWNvcmQucHJvdG90eXBlLndhc0FsdGVyZWQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9tYXAud2FzQWx0ZXJlZCgpO1xuICAgIH07XG5cbiAgICBSZWNvcmQucHJvdG90eXBlLl9faXRlcmF0b3IgPSBmdW5jdGlvbih0eXBlLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICByZXR1cm4gS2V5ZWRJdGVyYWJsZSh0aGlzLl9kZWZhdWx0VmFsdWVzKS5tYXAoZnVuY3Rpb24oXywgaykgIHtyZXR1cm4gdGhpcyQwLmdldChrKX0pLl9faXRlcmF0b3IodHlwZSwgcmV2ZXJzZSk7XG4gICAgfTtcblxuICAgIFJlY29yZC5wcm90b3R5cGUuX19pdGVyYXRlID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHt2YXIgdGhpcyQwID0gdGhpcztcbiAgICAgIHJldHVybiBLZXllZEl0ZXJhYmxlKHRoaXMuX2RlZmF1bHRWYWx1ZXMpLm1hcChmdW5jdGlvbihfLCBrKSAge3JldHVybiB0aGlzJDAuZ2V0KGspfSkuX19pdGVyYXRlKGZuLCByZXZlcnNlKTtcbiAgICB9O1xuXG4gICAgUmVjb3JkLnByb3RvdHlwZS5fX2Vuc3VyZU93bmVyID0gZnVuY3Rpb24ob3duZXJJRCkge1xuICAgICAgaWYgKG93bmVySUQgPT09IHRoaXMuX19vd25lcklEKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgdmFyIG5ld01hcCA9IHRoaXMuX21hcCAmJiB0aGlzLl9tYXAuX19lbnN1cmVPd25lcihvd25lcklEKTtcbiAgICAgIGlmICghb3duZXJJRCkge1xuICAgICAgICB0aGlzLl9fb3duZXJJRCA9IG93bmVySUQ7XG4gICAgICAgIHRoaXMuX21hcCA9IG5ld01hcDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWFrZVJlY29yZCh0aGlzLCBuZXdNYXAsIG93bmVySUQpO1xuICAgIH07XG5cblxuICB2YXIgUmVjb3JkUHJvdG90eXBlID0gUmVjb3JkLnByb3RvdHlwZTtcbiAgUmVjb3JkUHJvdG90eXBlW0RFTEVURV0gPSBSZWNvcmRQcm90b3R5cGUucmVtb3ZlO1xuICBSZWNvcmRQcm90b3R5cGUuZGVsZXRlSW4gPVxuICBSZWNvcmRQcm90b3R5cGUucmVtb3ZlSW4gPSBNYXBQcm90b3R5cGUucmVtb3ZlSW47XG4gIFJlY29yZFByb3RvdHlwZS5tZXJnZSA9IE1hcFByb3RvdHlwZS5tZXJnZTtcbiAgUmVjb3JkUHJvdG90eXBlLm1lcmdlV2l0aCA9IE1hcFByb3RvdHlwZS5tZXJnZVdpdGg7XG4gIFJlY29yZFByb3RvdHlwZS5tZXJnZUluID0gTWFwUHJvdG90eXBlLm1lcmdlSW47XG4gIFJlY29yZFByb3RvdHlwZS5tZXJnZURlZXAgPSBNYXBQcm90b3R5cGUubWVyZ2VEZWVwO1xuICBSZWNvcmRQcm90b3R5cGUubWVyZ2VEZWVwV2l0aCA9IE1hcFByb3RvdHlwZS5tZXJnZURlZXBXaXRoO1xuICBSZWNvcmRQcm90b3R5cGUubWVyZ2VEZWVwSW4gPSBNYXBQcm90b3R5cGUubWVyZ2VEZWVwSW47XG4gIFJlY29yZFByb3RvdHlwZS5zZXRJbiA9IE1hcFByb3RvdHlwZS5zZXRJbjtcbiAgUmVjb3JkUHJvdG90eXBlLnVwZGF0ZSA9IE1hcFByb3RvdHlwZS51cGRhdGU7XG4gIFJlY29yZFByb3RvdHlwZS51cGRhdGVJbiA9IE1hcFByb3RvdHlwZS51cGRhdGVJbjtcbiAgUmVjb3JkUHJvdG90eXBlLndpdGhNdXRhdGlvbnMgPSBNYXBQcm90b3R5cGUud2l0aE11dGF0aW9ucztcbiAgUmVjb3JkUHJvdG90eXBlLmFzTXV0YWJsZSA9IE1hcFByb3RvdHlwZS5hc011dGFibGU7XG4gIFJlY29yZFByb3RvdHlwZS5hc0ltbXV0YWJsZSA9IE1hcFByb3RvdHlwZS5hc0ltbXV0YWJsZTtcblxuXG4gIGZ1bmN0aW9uIG1ha2VSZWNvcmQobGlrZVJlY29yZCwgbWFwLCBvd25lcklEKSB7XG4gICAgdmFyIHJlY29yZCA9IE9iamVjdC5jcmVhdGUoT2JqZWN0LmdldFByb3RvdHlwZU9mKGxpa2VSZWNvcmQpKTtcbiAgICByZWNvcmQuX21hcCA9IG1hcDtcbiAgICByZWNvcmQuX19vd25lcklEID0gb3duZXJJRDtcbiAgICByZXR1cm4gcmVjb3JkO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVjb3JkTmFtZShyZWNvcmQpIHtcbiAgICByZXR1cm4gcmVjb3JkLl9uYW1lIHx8IHJlY29yZC5jb25zdHJ1Y3Rvci5uYW1lIHx8ICdSZWNvcmQnO1xuICB9XG5cbiAgZnVuY3Rpb24gc2V0UHJvcHMocHJvdG90eXBlLCBuYW1lcykge1xuICAgIHRyeSB7XG4gICAgICBuYW1lcy5mb3JFYWNoKHNldFByb3AuYmluZCh1bmRlZmluZWQsIHByb3RvdHlwZSkpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBPYmplY3QuZGVmaW5lUHJvcGVydHkgZmFpbGVkLiBQcm9iYWJseSBJRTguXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc2V0UHJvcChwcm90b3R5cGUsIG5hbWUpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvdG90eXBlLCBuYW1lLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXQobmFtZSk7XG4gICAgICB9LFxuICAgICAgc2V0OiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICBpbnZhcmlhbnQodGhpcy5fX293bmVySUQsICdDYW5ub3Qgc2V0IG9uIGFuIGltbXV0YWJsZSByZWNvcmQuJyk7XG4gICAgICAgIHRoaXMuc2V0KG5hbWUsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKFNldCwgU2V0Q29sbGVjdGlvbik7XG5cbiAgICAvLyBAcHJhZ21hIENvbnN0cnVjdGlvblxuXG4gICAgZnVuY3Rpb24gU2V0KHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCA/IGVtcHR5U2V0KCkgOlxuICAgICAgICBpc1NldCh2YWx1ZSkgJiYgIWlzT3JkZXJlZCh2YWx1ZSkgPyB2YWx1ZSA6XG4gICAgICAgIGVtcHR5U2V0KCkud2l0aE11dGF0aW9ucyhmdW5jdGlvbihzZXQgKSB7XG4gICAgICAgICAgdmFyIGl0ZXIgPSBTZXRJdGVyYWJsZSh2YWx1ZSk7XG4gICAgICAgICAgYXNzZXJ0Tm90SW5maW5pdGUoaXRlci5zaXplKTtcbiAgICAgICAgICBpdGVyLmZvckVhY2goZnVuY3Rpb24odiApIHtyZXR1cm4gc2V0LmFkZCh2KX0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBTZXQub2YgPSBmdW5jdGlvbigvKi4uLnZhbHVlcyovKSB7XG4gICAgICByZXR1cm4gdGhpcyhhcmd1bWVudHMpO1xuICAgIH07XG5cbiAgICBTZXQuZnJvbUtleXMgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMoS2V5ZWRJdGVyYWJsZSh2YWx1ZSkua2V5U2VxKCkpO1xuICAgIH07XG5cbiAgICBTZXQucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fX3RvU3RyaW5nKCdTZXQgeycsICd9Jyk7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgQWNjZXNzXG5cbiAgICBTZXQucHJvdG90eXBlLmhhcyA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbWFwLmhhcyh2YWx1ZSk7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgTW9kaWZpY2F0aW9uXG5cbiAgICBTZXQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdXBkYXRlU2V0KHRoaXMsIHRoaXMuX21hcC5zZXQodmFsdWUsIHRydWUpKTtcbiAgICB9O1xuXG4gICAgU2V0LnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHVwZGF0ZVNldCh0aGlzLCB0aGlzLl9tYXAucmVtb3ZlKHZhbHVlKSk7XG4gICAgfTtcblxuICAgIFNldC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB1cGRhdGVTZXQodGhpcywgdGhpcy5fbWFwLmNsZWFyKCkpO1xuICAgIH07XG5cbiAgICAvLyBAcHJhZ21hIENvbXBvc2l0aW9uXG5cbiAgICBTZXQucHJvdG90eXBlLnVuaW9uID0gZnVuY3Rpb24oKSB7dmFyIGl0ZXJzID0gU0xJQ0UkMC5jYWxsKGFyZ3VtZW50cywgMCk7XG4gICAgICBpdGVycyA9IGl0ZXJzLmZpbHRlcihmdW5jdGlvbih4ICkge3JldHVybiB4LnNpemUgIT09IDB9KTtcbiAgICAgIGlmIChpdGVycy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5zaXplID09PSAwICYmICF0aGlzLl9fb3duZXJJRCAmJiBpdGVycy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IoaXRlcnNbMF0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMud2l0aE11dGF0aW9ucyhmdW5jdGlvbihzZXQgKSB7XG4gICAgICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCBpdGVycy5sZW5ndGg7IGlpKyspIHtcbiAgICAgICAgICBTZXRJdGVyYWJsZShpdGVyc1tpaV0pLmZvckVhY2goZnVuY3Rpb24odmFsdWUgKSB7cmV0dXJuIHNldC5hZGQodmFsdWUpfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBTZXQucHJvdG90eXBlLmludGVyc2VjdCA9IGZ1bmN0aW9uKCkge3ZhciBpdGVycyA9IFNMSUNFJDAuY2FsbChhcmd1bWVudHMsIDApO1xuICAgICAgaWYgKGl0ZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGl0ZXJzID0gaXRlcnMubWFwKGZ1bmN0aW9uKGl0ZXIgKSB7cmV0dXJuIFNldEl0ZXJhYmxlKGl0ZXIpfSk7XG4gICAgICB2YXIgb3JpZ2luYWxTZXQgPSB0aGlzO1xuICAgICAgcmV0dXJuIHRoaXMud2l0aE11dGF0aW9ucyhmdW5jdGlvbihzZXQgKSB7XG4gICAgICAgIG9yaWdpbmFsU2V0LmZvckVhY2goZnVuY3Rpb24odmFsdWUgKSB7XG4gICAgICAgICAgaWYgKCFpdGVycy5ldmVyeShmdW5jdGlvbihpdGVyICkge3JldHVybiBpdGVyLmluY2x1ZGVzKHZhbHVlKX0pKSB7XG4gICAgICAgICAgICBzZXQucmVtb3ZlKHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIFNldC5wcm90b3R5cGUuc3VidHJhY3QgPSBmdW5jdGlvbigpIHt2YXIgaXRlcnMgPSBTTElDRSQwLmNhbGwoYXJndW1lbnRzLCAwKTtcbiAgICAgIGlmIChpdGVycy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICBpdGVycyA9IGl0ZXJzLm1hcChmdW5jdGlvbihpdGVyICkge3JldHVybiBTZXRJdGVyYWJsZShpdGVyKX0pO1xuICAgICAgdmFyIG9yaWdpbmFsU2V0ID0gdGhpcztcbiAgICAgIHJldHVybiB0aGlzLndpdGhNdXRhdGlvbnMoZnVuY3Rpb24oc2V0ICkge1xuICAgICAgICBvcmlnaW5hbFNldC5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlICkge1xuICAgICAgICAgIGlmIChpdGVycy5zb21lKGZ1bmN0aW9uKGl0ZXIgKSB7cmV0dXJuIGl0ZXIuaW5jbHVkZXModmFsdWUpfSkpIHtcbiAgICAgICAgICAgIHNldC5yZW1vdmUodmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgU2V0LnByb3RvdHlwZS5tZXJnZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMudW5pb24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgU2V0LnByb3RvdHlwZS5tZXJnZVdpdGggPSBmdW5jdGlvbihtZXJnZXIpIHt2YXIgaXRlcnMgPSBTTElDRSQwLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgIHJldHVybiB0aGlzLnVuaW9uLmFwcGx5KHRoaXMsIGl0ZXJzKTtcbiAgICB9O1xuXG4gICAgU2V0LnByb3RvdHlwZS5zb3J0ID0gZnVuY3Rpb24oY29tcGFyYXRvcikge1xuICAgICAgLy8gTGF0ZSBiaW5kaW5nXG4gICAgICByZXR1cm4gT3JkZXJlZFNldChzb3J0RmFjdG9yeSh0aGlzLCBjb21wYXJhdG9yKSk7XG4gICAgfTtcblxuICAgIFNldC5wcm90b3R5cGUuc29ydEJ5ID0gZnVuY3Rpb24obWFwcGVyLCBjb21wYXJhdG9yKSB7XG4gICAgICAvLyBMYXRlIGJpbmRpbmdcbiAgICAgIHJldHVybiBPcmRlcmVkU2V0KHNvcnRGYWN0b3J5KHRoaXMsIGNvbXBhcmF0b3IsIG1hcHBlcikpO1xuICAgIH07XG5cbiAgICBTZXQucHJvdG90eXBlLndhc0FsdGVyZWQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9tYXAud2FzQWx0ZXJlZCgpO1xuICAgIH07XG5cbiAgICBTZXQucHJvdG90eXBlLl9faXRlcmF0ZSA9IGZ1bmN0aW9uKGZuLCByZXZlcnNlKSB7dmFyIHRoaXMkMCA9IHRoaXM7XG4gICAgICByZXR1cm4gdGhpcy5fbWFwLl9faXRlcmF0ZShmdW5jdGlvbihfLCBrKSAge3JldHVybiBmbihrLCBrLCB0aGlzJDApfSwgcmV2ZXJzZSk7XG4gICAgfTtcblxuICAgIFNldC5wcm90b3R5cGUuX19pdGVyYXRvciA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIHJldHVybiB0aGlzLl9tYXAubWFwKGZ1bmN0aW9uKF8sIGspICB7cmV0dXJuIGt9KS5fX2l0ZXJhdG9yKHR5cGUsIHJldmVyc2UpO1xuICAgIH07XG5cbiAgICBTZXQucHJvdG90eXBlLl9fZW5zdXJlT3duZXIgPSBmdW5jdGlvbihvd25lcklEKSB7XG4gICAgICBpZiAob3duZXJJRCA9PT0gdGhpcy5fX293bmVySUQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICB2YXIgbmV3TWFwID0gdGhpcy5fbWFwLl9fZW5zdXJlT3duZXIob3duZXJJRCk7XG4gICAgICBpZiAoIW93bmVySUQpIHtcbiAgICAgICAgdGhpcy5fX293bmVySUQgPSBvd25lcklEO1xuICAgICAgICB0aGlzLl9tYXAgPSBuZXdNYXA7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuX19tYWtlKG5ld01hcCwgb3duZXJJRCk7XG4gICAgfTtcblxuXG4gIGZ1bmN0aW9uIGlzU2V0KG1heWJlU2V0KSB7XG4gICAgcmV0dXJuICEhKG1heWJlU2V0ICYmIG1heWJlU2V0W0lTX1NFVF9TRU5USU5FTF0pO1xuICB9XG5cbiAgU2V0LmlzU2V0ID0gaXNTZXQ7XG5cbiAgdmFyIElTX1NFVF9TRU5USU5FTCA9ICdAQF9fSU1NVVRBQkxFX1NFVF9fQEAnO1xuXG4gIHZhciBTZXRQcm90b3R5cGUgPSBTZXQucHJvdG90eXBlO1xuICBTZXRQcm90b3R5cGVbSVNfU0VUX1NFTlRJTkVMXSA9IHRydWU7XG4gIFNldFByb3RvdHlwZVtERUxFVEVdID0gU2V0UHJvdG90eXBlLnJlbW92ZTtcbiAgU2V0UHJvdG90eXBlLm1lcmdlRGVlcCA9IFNldFByb3RvdHlwZS5tZXJnZTtcbiAgU2V0UHJvdG90eXBlLm1lcmdlRGVlcFdpdGggPSBTZXRQcm90b3R5cGUubWVyZ2VXaXRoO1xuICBTZXRQcm90b3R5cGUud2l0aE11dGF0aW9ucyA9IE1hcFByb3RvdHlwZS53aXRoTXV0YXRpb25zO1xuICBTZXRQcm90b3R5cGUuYXNNdXRhYmxlID0gTWFwUHJvdG90eXBlLmFzTXV0YWJsZTtcbiAgU2V0UHJvdG90eXBlLmFzSW1tdXRhYmxlID0gTWFwUHJvdG90eXBlLmFzSW1tdXRhYmxlO1xuXG4gIFNldFByb3RvdHlwZS5fX2VtcHR5ID0gZW1wdHlTZXQ7XG4gIFNldFByb3RvdHlwZS5fX21ha2UgPSBtYWtlU2V0O1xuXG4gIGZ1bmN0aW9uIHVwZGF0ZVNldChzZXQsIG5ld01hcCkge1xuICAgIGlmIChzZXQuX19vd25lcklEKSB7XG4gICAgICBzZXQuc2l6ZSA9IG5ld01hcC5zaXplO1xuICAgICAgc2V0Ll9tYXAgPSBuZXdNYXA7XG4gICAgICByZXR1cm4gc2V0O1xuICAgIH1cbiAgICByZXR1cm4gbmV3TWFwID09PSBzZXQuX21hcCA/IHNldCA6XG4gICAgICBuZXdNYXAuc2l6ZSA9PT0gMCA/IHNldC5fX2VtcHR5KCkgOlxuICAgICAgc2V0Ll9fbWFrZShuZXdNYXApO1xuICB9XG5cbiAgZnVuY3Rpb24gbWFrZVNldChtYXAsIG93bmVySUQpIHtcbiAgICB2YXIgc2V0ID0gT2JqZWN0LmNyZWF0ZShTZXRQcm90b3R5cGUpO1xuICAgIHNldC5zaXplID0gbWFwID8gbWFwLnNpemUgOiAwO1xuICAgIHNldC5fbWFwID0gbWFwO1xuICAgIHNldC5fX293bmVySUQgPSBvd25lcklEO1xuICAgIHJldHVybiBzZXQ7XG4gIH1cblxuICB2YXIgRU1QVFlfU0VUO1xuICBmdW5jdGlvbiBlbXB0eVNldCgpIHtcbiAgICByZXR1cm4gRU1QVFlfU0VUIHx8IChFTVBUWV9TRVQgPSBtYWtlU2V0KGVtcHR5TWFwKCkpKTtcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKE9yZGVyZWRTZXQsIFNldCk7XG5cbiAgICAvLyBAcHJhZ21hIENvbnN0cnVjdGlvblxuXG4gICAgZnVuY3Rpb24gT3JkZXJlZFNldCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgPyBlbXB0eU9yZGVyZWRTZXQoKSA6XG4gICAgICAgIGlzT3JkZXJlZFNldCh2YWx1ZSkgPyB2YWx1ZSA6XG4gICAgICAgIGVtcHR5T3JkZXJlZFNldCgpLndpdGhNdXRhdGlvbnMoZnVuY3Rpb24oc2V0ICkge1xuICAgICAgICAgIHZhciBpdGVyID0gU2V0SXRlcmFibGUodmFsdWUpO1xuICAgICAgICAgIGFzc2VydE5vdEluZmluaXRlKGl0ZXIuc2l6ZSk7XG4gICAgICAgICAgaXRlci5mb3JFYWNoKGZ1bmN0aW9uKHYgKSB7cmV0dXJuIHNldC5hZGQodil9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgT3JkZXJlZFNldC5vZiA9IGZ1bmN0aW9uKC8qLi4udmFsdWVzKi8pIHtcbiAgICAgIHJldHVybiB0aGlzKGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIE9yZGVyZWRTZXQuZnJvbUtleXMgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMoS2V5ZWRJdGVyYWJsZSh2YWx1ZSkua2V5U2VxKCkpO1xuICAgIH07XG5cbiAgICBPcmRlcmVkU2V0LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX190b1N0cmluZygnT3JkZXJlZFNldCB7JywgJ30nKTtcbiAgICB9O1xuXG5cbiAgZnVuY3Rpb24gaXNPcmRlcmVkU2V0KG1heWJlT3JkZXJlZFNldCkge1xuICAgIHJldHVybiBpc1NldChtYXliZU9yZGVyZWRTZXQpICYmIGlzT3JkZXJlZChtYXliZU9yZGVyZWRTZXQpO1xuICB9XG5cbiAgT3JkZXJlZFNldC5pc09yZGVyZWRTZXQgPSBpc09yZGVyZWRTZXQ7XG5cbiAgdmFyIE9yZGVyZWRTZXRQcm90b3R5cGUgPSBPcmRlcmVkU2V0LnByb3RvdHlwZTtcbiAgT3JkZXJlZFNldFByb3RvdHlwZVtJU19PUkRFUkVEX1NFTlRJTkVMXSA9IHRydWU7XG5cbiAgT3JkZXJlZFNldFByb3RvdHlwZS5fX2VtcHR5ID0gZW1wdHlPcmRlcmVkU2V0O1xuICBPcmRlcmVkU2V0UHJvdG90eXBlLl9fbWFrZSA9IG1ha2VPcmRlcmVkU2V0O1xuXG4gIGZ1bmN0aW9uIG1ha2VPcmRlcmVkU2V0KG1hcCwgb3duZXJJRCkge1xuICAgIHZhciBzZXQgPSBPYmplY3QuY3JlYXRlKE9yZGVyZWRTZXRQcm90b3R5cGUpO1xuICAgIHNldC5zaXplID0gbWFwID8gbWFwLnNpemUgOiAwO1xuICAgIHNldC5fbWFwID0gbWFwO1xuICAgIHNldC5fX293bmVySUQgPSBvd25lcklEO1xuICAgIHJldHVybiBzZXQ7XG4gIH1cblxuICB2YXIgRU1QVFlfT1JERVJFRF9TRVQ7XG4gIGZ1bmN0aW9uIGVtcHR5T3JkZXJlZFNldCgpIHtcbiAgICByZXR1cm4gRU1QVFlfT1JERVJFRF9TRVQgfHwgKEVNUFRZX09SREVSRURfU0VUID0gbWFrZU9yZGVyZWRTZXQoZW1wdHlPcmRlcmVkTWFwKCkpKTtcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKFN0YWNrLCBJbmRleGVkQ29sbGVjdGlvbik7XG5cbiAgICAvLyBAcHJhZ21hIENvbnN0cnVjdGlvblxuXG4gICAgZnVuY3Rpb24gU3RhY2sodmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gZW1wdHlTdGFjaygpIDpcbiAgICAgICAgaXNTdGFjayh2YWx1ZSkgPyB2YWx1ZSA6XG4gICAgICAgIGVtcHR5U3RhY2soKS51bnNoaWZ0QWxsKHZhbHVlKTtcbiAgICB9XG5cbiAgICBTdGFjay5vZiA9IGZ1bmN0aW9uKC8qLi4udmFsdWVzKi8pIHtcbiAgICAgIHJldHVybiB0aGlzKGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIFN0YWNrLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX190b1N0cmluZygnU3RhY2sgWycsICddJyk7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgQWNjZXNzXG5cbiAgICBTdGFjay5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oaW5kZXgsIG5vdFNldFZhbHVlKSB7XG4gICAgICB2YXIgaGVhZCA9IHRoaXMuX2hlYWQ7XG4gICAgICBpbmRleCA9IHdyYXBJbmRleCh0aGlzLCBpbmRleCk7XG4gICAgICB3aGlsZSAoaGVhZCAmJiBpbmRleC0tKSB7XG4gICAgICAgIGhlYWQgPSBoZWFkLm5leHQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gaGVhZCA/IGhlYWQudmFsdWUgOiBub3RTZXRWYWx1ZTtcbiAgICB9O1xuXG4gICAgU3RhY2sucHJvdG90eXBlLnBlZWsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9oZWFkICYmIHRoaXMuX2hlYWQudmFsdWU7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgTW9kaWZpY2F0aW9uXG5cbiAgICBTdGFjay5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uKC8qLi4udmFsdWVzKi8pIHtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgdmFyIG5ld1NpemUgPSB0aGlzLnNpemUgKyBhcmd1bWVudHMubGVuZ3RoO1xuICAgICAgdmFyIGhlYWQgPSB0aGlzLl9oZWFkO1xuICAgICAgZm9yICh2YXIgaWkgPSBhcmd1bWVudHMubGVuZ3RoIC0gMTsgaWkgPj0gMDsgaWktLSkge1xuICAgICAgICBoZWFkID0ge1xuICAgICAgICAgIHZhbHVlOiBhcmd1bWVudHNbaWldLFxuICAgICAgICAgIG5leHQ6IGhlYWRcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9fb3duZXJJRCkge1xuICAgICAgICB0aGlzLnNpemUgPSBuZXdTaXplO1xuICAgICAgICB0aGlzLl9oZWFkID0gaGVhZDtcbiAgICAgICAgdGhpcy5fX2hhc2ggPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX19hbHRlcmVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWFrZVN0YWNrKG5ld1NpemUsIGhlYWQpO1xuICAgIH07XG5cbiAgICBTdGFjay5wcm90b3R5cGUucHVzaEFsbCA9IGZ1bmN0aW9uKGl0ZXIpIHtcbiAgICAgIGl0ZXIgPSBJbmRleGVkSXRlcmFibGUoaXRlcik7XG4gICAgICBpZiAoaXRlci5zaXplID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgYXNzZXJ0Tm90SW5maW5pdGUoaXRlci5zaXplKTtcbiAgICAgIHZhciBuZXdTaXplID0gdGhpcy5zaXplO1xuICAgICAgdmFyIGhlYWQgPSB0aGlzLl9oZWFkO1xuICAgICAgaXRlci5yZXZlcnNlKCkuZm9yRWFjaChmdW5jdGlvbih2YWx1ZSApIHtcbiAgICAgICAgbmV3U2l6ZSsrO1xuICAgICAgICBoZWFkID0ge1xuICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICBuZXh0OiBoZWFkXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICAgIGlmICh0aGlzLl9fb3duZXJJRCkge1xuICAgICAgICB0aGlzLnNpemUgPSBuZXdTaXplO1xuICAgICAgICB0aGlzLl9oZWFkID0gaGVhZDtcbiAgICAgICAgdGhpcy5fX2hhc2ggPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX19hbHRlcmVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWFrZVN0YWNrKG5ld1NpemUsIGhlYWQpO1xuICAgIH07XG5cbiAgICBTdGFjay5wcm90b3R5cGUucG9wID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5zbGljZSgxKTtcbiAgICB9O1xuXG4gICAgU3RhY2sucHJvdG90eXBlLnVuc2hpZnQgPSBmdW5jdGlvbigvKi4uLnZhbHVlcyovKSB7XG4gICAgICByZXR1cm4gdGhpcy5wdXNoLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIFN0YWNrLnByb3RvdHlwZS51bnNoaWZ0QWxsID0gZnVuY3Rpb24oaXRlcikge1xuICAgICAgcmV0dXJuIHRoaXMucHVzaEFsbChpdGVyKTtcbiAgICB9O1xuXG4gICAgU3RhY2sucHJvdG90eXBlLnNoaWZ0ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5wb3AuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgU3RhY2sucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5zaXplID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuX19vd25lcklEKSB7XG4gICAgICAgIHRoaXMuc2l6ZSA9IDA7XG4gICAgICAgIHRoaXMuX2hlYWQgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX19oYXNoID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9fYWx0ZXJlZCA9IHRydWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGVtcHR5U3RhY2soKTtcbiAgICB9O1xuXG4gICAgU3RhY2sucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24oYmVnaW4sIGVuZCkge1xuICAgICAgaWYgKHdob2xlU2xpY2UoYmVnaW4sIGVuZCwgdGhpcy5zaXplKSkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHZhciByZXNvbHZlZEJlZ2luID0gcmVzb2x2ZUJlZ2luKGJlZ2luLCB0aGlzLnNpemUpO1xuICAgICAgdmFyIHJlc29sdmVkRW5kID0gcmVzb2x2ZUVuZChlbmQsIHRoaXMuc2l6ZSk7XG4gICAgICBpZiAocmVzb2x2ZWRFbmQgIT09IHRoaXMuc2l6ZSkge1xuICAgICAgICAvLyBzdXBlci5zbGljZShiZWdpbiwgZW5kKTtcbiAgICAgICAgcmV0dXJuIEluZGV4ZWRDb2xsZWN0aW9uLnByb3RvdHlwZS5zbGljZS5jYWxsKHRoaXMsIGJlZ2luLCBlbmQpO1xuICAgICAgfVxuICAgICAgdmFyIG5ld1NpemUgPSB0aGlzLnNpemUgLSByZXNvbHZlZEJlZ2luO1xuICAgICAgdmFyIGhlYWQgPSB0aGlzLl9oZWFkO1xuICAgICAgd2hpbGUgKHJlc29sdmVkQmVnaW4tLSkge1xuICAgICAgICBoZWFkID0gaGVhZC5uZXh0O1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuX19vd25lcklEKSB7XG4gICAgICAgIHRoaXMuc2l6ZSA9IG5ld1NpemU7XG4gICAgICAgIHRoaXMuX2hlYWQgPSBoZWFkO1xuICAgICAgICB0aGlzLl9faGFzaCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fX2FsdGVyZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBtYWtlU3RhY2sobmV3U2l6ZSwgaGVhZCk7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgTXV0YWJpbGl0eVxuXG4gICAgU3RhY2sucHJvdG90eXBlLl9fZW5zdXJlT3duZXIgPSBmdW5jdGlvbihvd25lcklEKSB7XG4gICAgICBpZiAob3duZXJJRCA9PT0gdGhpcy5fX293bmVySUQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICBpZiAoIW93bmVySUQpIHtcbiAgICAgICAgdGhpcy5fX293bmVySUQgPSBvd25lcklEO1xuICAgICAgICB0aGlzLl9fYWx0ZXJlZCA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBtYWtlU3RhY2sodGhpcy5zaXplLCB0aGlzLl9oZWFkLCBvd25lcklELCB0aGlzLl9faGFzaCk7XG4gICAgfTtcblxuICAgIC8vIEBwcmFnbWEgSXRlcmF0aW9uXG5cbiAgICBTdGFjay5wcm90b3R5cGUuX19pdGVyYXRlID0gZnVuY3Rpb24oZm4sIHJldmVyc2UpIHtcbiAgICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJldmVyc2UoKS5fX2l0ZXJhdGUoZm4pO1xuICAgICAgfVxuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgdmFyIG5vZGUgPSB0aGlzLl9oZWFkO1xuICAgICAgd2hpbGUgKG5vZGUpIHtcbiAgICAgICAgaWYgKGZuKG5vZGUudmFsdWUsIGl0ZXJhdGlvbnMrKywgdGhpcykgPT09IGZhbHNlKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgbm9kZSA9IG5vZGUubmV4dDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpdGVyYXRpb25zO1xuICAgIH07XG5cbiAgICBTdGFjay5wcm90b3R5cGUuX19pdGVyYXRvciA9IGZ1bmN0aW9uKHR5cGUsIHJldmVyc2UpIHtcbiAgICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJldmVyc2UoKS5fX2l0ZXJhdG9yKHR5cGUpO1xuICAgICAgfVxuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgdmFyIG5vZGUgPSB0aGlzLl9oZWFkO1xuICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcihmdW5jdGlvbigpICB7XG4gICAgICAgIGlmIChub2RlKSB7XG4gICAgICAgICAgdmFyIHZhbHVlID0gbm9kZS52YWx1ZTtcbiAgICAgICAgICBub2RlID0gbm9kZS5uZXh0O1xuICAgICAgICAgIHJldHVybiBpdGVyYXRvclZhbHVlKHR5cGUsIGl0ZXJhdGlvbnMrKywgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpdGVyYXRvckRvbmUoKTtcbiAgICAgIH0pO1xuICAgIH07XG5cblxuICBmdW5jdGlvbiBpc1N0YWNrKG1heWJlU3RhY2spIHtcbiAgICByZXR1cm4gISEobWF5YmVTdGFjayAmJiBtYXliZVN0YWNrW0lTX1NUQUNLX1NFTlRJTkVMXSk7XG4gIH1cblxuICBTdGFjay5pc1N0YWNrID0gaXNTdGFjaztcblxuICB2YXIgSVNfU1RBQ0tfU0VOVElORUwgPSAnQEBfX0lNTVVUQUJMRV9TVEFDS19fQEAnO1xuXG4gIHZhciBTdGFja1Byb3RvdHlwZSA9IFN0YWNrLnByb3RvdHlwZTtcbiAgU3RhY2tQcm90b3R5cGVbSVNfU1RBQ0tfU0VOVElORUxdID0gdHJ1ZTtcbiAgU3RhY2tQcm90b3R5cGUud2l0aE11dGF0aW9ucyA9IE1hcFByb3RvdHlwZS53aXRoTXV0YXRpb25zO1xuICBTdGFja1Byb3RvdHlwZS5hc011dGFibGUgPSBNYXBQcm90b3R5cGUuYXNNdXRhYmxlO1xuICBTdGFja1Byb3RvdHlwZS5hc0ltbXV0YWJsZSA9IE1hcFByb3RvdHlwZS5hc0ltbXV0YWJsZTtcbiAgU3RhY2tQcm90b3R5cGUud2FzQWx0ZXJlZCA9IE1hcFByb3RvdHlwZS53YXNBbHRlcmVkO1xuXG5cbiAgZnVuY3Rpb24gbWFrZVN0YWNrKHNpemUsIGhlYWQsIG93bmVySUQsIGhhc2gpIHtcbiAgICB2YXIgbWFwID0gT2JqZWN0LmNyZWF0ZShTdGFja1Byb3RvdHlwZSk7XG4gICAgbWFwLnNpemUgPSBzaXplO1xuICAgIG1hcC5faGVhZCA9IGhlYWQ7XG4gICAgbWFwLl9fb3duZXJJRCA9IG93bmVySUQ7XG4gICAgbWFwLl9faGFzaCA9IGhhc2g7XG4gICAgbWFwLl9fYWx0ZXJlZCA9IGZhbHNlO1xuICAgIHJldHVybiBtYXA7XG4gIH1cblxuICB2YXIgRU1QVFlfU1RBQ0s7XG4gIGZ1bmN0aW9uIGVtcHR5U3RhY2soKSB7XG4gICAgcmV0dXJuIEVNUFRZX1NUQUNLIHx8IChFTVBUWV9TVEFDSyA9IG1ha2VTdGFjaygwKSk7XG4gIH1cblxuICAvKipcbiAgICogQ29udHJpYnV0ZXMgYWRkaXRpb25hbCBtZXRob2RzIHRvIGEgY29uc3RydWN0b3JcbiAgICovXG4gIGZ1bmN0aW9uIG1peGluKGN0b3IsIG1ldGhvZHMpIHtcbiAgICB2YXIga2V5Q29waWVyID0gZnVuY3Rpb24oa2V5ICkgeyBjdG9yLnByb3RvdHlwZVtrZXldID0gbWV0aG9kc1trZXldOyB9O1xuICAgIE9iamVjdC5rZXlzKG1ldGhvZHMpLmZvckVhY2goa2V5Q29waWVyKTtcbiAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzICYmXG4gICAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKG1ldGhvZHMpLmZvckVhY2goa2V5Q29waWVyKTtcbiAgICByZXR1cm4gY3RvcjtcbiAgfVxuXG4gIEl0ZXJhYmxlLkl0ZXJhdG9yID0gSXRlcmF0b3I7XG5cbiAgbWl4aW4oSXRlcmFibGUsIHtcblxuICAgIC8vICMjIyBDb252ZXJzaW9uIHRvIG90aGVyIHR5cGVzXG5cbiAgICB0b0FycmF5OiBmdW5jdGlvbigpIHtcbiAgICAgIGFzc2VydE5vdEluZmluaXRlKHRoaXMuc2l6ZSk7XG4gICAgICB2YXIgYXJyYXkgPSBuZXcgQXJyYXkodGhpcy5zaXplIHx8IDApO1xuICAgICAgdGhpcy52YWx1ZVNlcSgpLl9faXRlcmF0ZShmdW5jdGlvbih2LCBpKSAgeyBhcnJheVtpXSA9IHY7IH0pO1xuICAgICAgcmV0dXJuIGFycmF5O1xuICAgIH0sXG5cbiAgICB0b0luZGV4ZWRTZXE6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIG5ldyBUb0luZGV4ZWRTZXF1ZW5jZSh0aGlzKTtcbiAgICB9LFxuXG4gICAgdG9KUzogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy50b1NlcSgpLm1hcChcbiAgICAgICAgZnVuY3Rpb24odmFsdWUgKSB7cmV0dXJuIHZhbHVlICYmIHR5cGVvZiB2YWx1ZS50b0pTID09PSAnZnVuY3Rpb24nID8gdmFsdWUudG9KUygpIDogdmFsdWV9XG4gICAgICApLl9fdG9KUygpO1xuICAgIH0sXG5cbiAgICB0b0pTT046IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMudG9TZXEoKS5tYXAoXG4gICAgICAgIGZ1bmN0aW9uKHZhbHVlICkge3JldHVybiB2YWx1ZSAmJiB0eXBlb2YgdmFsdWUudG9KU09OID09PSAnZnVuY3Rpb24nID8gdmFsdWUudG9KU09OKCkgOiB2YWx1ZX1cbiAgICAgICkuX190b0pTKCk7XG4gICAgfSxcblxuICAgIHRvS2V5ZWRTZXE6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIG5ldyBUb0tleWVkU2VxdWVuY2UodGhpcywgdHJ1ZSk7XG4gICAgfSxcblxuICAgIHRvTWFwOiBmdW5jdGlvbigpIHtcbiAgICAgIC8vIFVzZSBMYXRlIEJpbmRpbmcgaGVyZSB0byBzb2x2ZSB0aGUgY2lyY3VsYXIgZGVwZW5kZW5jeS5cbiAgICAgIHJldHVybiBNYXAodGhpcy50b0tleWVkU2VxKCkpO1xuICAgIH0sXG5cbiAgICB0b09iamVjdDogZnVuY3Rpb24oKSB7XG4gICAgICBhc3NlcnROb3RJbmZpbml0ZSh0aGlzLnNpemUpO1xuICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgdGhpcy5fX2l0ZXJhdGUoZnVuY3Rpb24odiwgaykgIHsgb2JqZWN0W2tdID0gdjsgfSk7XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH0sXG5cbiAgICB0b09yZGVyZWRNYXA6IGZ1bmN0aW9uKCkge1xuICAgICAgLy8gVXNlIExhdGUgQmluZGluZyBoZXJlIHRvIHNvbHZlIHRoZSBjaXJjdWxhciBkZXBlbmRlbmN5LlxuICAgICAgcmV0dXJuIE9yZGVyZWRNYXAodGhpcy50b0tleWVkU2VxKCkpO1xuICAgIH0sXG5cbiAgICB0b09yZGVyZWRTZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgLy8gVXNlIExhdGUgQmluZGluZyBoZXJlIHRvIHNvbHZlIHRoZSBjaXJjdWxhciBkZXBlbmRlbmN5LlxuICAgICAgcmV0dXJuIE9yZGVyZWRTZXQoaXNLZXllZCh0aGlzKSA/IHRoaXMudmFsdWVTZXEoKSA6IHRoaXMpO1xuICAgIH0sXG5cbiAgICB0b1NldDogZnVuY3Rpb24oKSB7XG4gICAgICAvLyBVc2UgTGF0ZSBCaW5kaW5nIGhlcmUgdG8gc29sdmUgdGhlIGNpcmN1bGFyIGRlcGVuZGVuY3kuXG4gICAgICByZXR1cm4gU2V0KGlzS2V5ZWQodGhpcykgPyB0aGlzLnZhbHVlU2VxKCkgOiB0aGlzKTtcbiAgICB9LFxuXG4gICAgdG9TZXRTZXE6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIG5ldyBUb1NldFNlcXVlbmNlKHRoaXMpO1xuICAgIH0sXG5cbiAgICB0b1NlcTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gaXNJbmRleGVkKHRoaXMpID8gdGhpcy50b0luZGV4ZWRTZXEoKSA6XG4gICAgICAgIGlzS2V5ZWQodGhpcykgPyB0aGlzLnRvS2V5ZWRTZXEoKSA6XG4gICAgICAgIHRoaXMudG9TZXRTZXEoKTtcbiAgICB9LFxuXG4gICAgdG9TdGFjazogZnVuY3Rpb24oKSB7XG4gICAgICAvLyBVc2UgTGF0ZSBCaW5kaW5nIGhlcmUgdG8gc29sdmUgdGhlIGNpcmN1bGFyIGRlcGVuZGVuY3kuXG4gICAgICByZXR1cm4gU3RhY2soaXNLZXllZCh0aGlzKSA/IHRoaXMudmFsdWVTZXEoKSA6IHRoaXMpO1xuICAgIH0sXG5cbiAgICB0b0xpc3Q6IGZ1bmN0aW9uKCkge1xuICAgICAgLy8gVXNlIExhdGUgQmluZGluZyBoZXJlIHRvIHNvbHZlIHRoZSBjaXJjdWxhciBkZXBlbmRlbmN5LlxuICAgICAgcmV0dXJuIExpc3QoaXNLZXllZCh0aGlzKSA/IHRoaXMudmFsdWVTZXEoKSA6IHRoaXMpO1xuICAgIH0sXG5cblxuICAgIC8vICMjIyBDb21tb24gSmF2YVNjcmlwdCBtZXRob2RzIGFuZCBwcm9wZXJ0aWVzXG5cbiAgICB0b1N0cmluZzogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gJ1tJdGVyYWJsZV0nO1xuICAgIH0sXG5cbiAgICBfX3RvU3RyaW5nOiBmdW5jdGlvbihoZWFkLCB0YWlsKSB7XG4gICAgICBpZiAodGhpcy5zaXplID09PSAwKSB7XG4gICAgICAgIHJldHVybiBoZWFkICsgdGFpbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBoZWFkICsgJyAnICsgdGhpcy50b1NlcSgpLm1hcCh0aGlzLl9fdG9TdHJpbmdNYXBwZXIpLmpvaW4oJywgJykgKyAnICcgKyB0YWlsO1xuICAgIH0sXG5cblxuICAgIC8vICMjIyBFUzYgQ29sbGVjdGlvbiBtZXRob2RzIChFUzYgQXJyYXkgYW5kIE1hcClcblxuICAgIGNvbmNhdDogZnVuY3Rpb24oKSB7dmFyIHZhbHVlcyA9IFNMSUNFJDAuY2FsbChhcmd1bWVudHMsIDApO1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIGNvbmNhdEZhY3RvcnkodGhpcywgdmFsdWVzKSk7XG4gICAgfSxcblxuICAgIGluY2x1ZGVzOiBmdW5jdGlvbihzZWFyY2hWYWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuc29tZShmdW5jdGlvbih2YWx1ZSApIHtyZXR1cm4gaXModmFsdWUsIHNlYXJjaFZhbHVlKX0pO1xuICAgIH0sXG5cbiAgICBlbnRyaWVzOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9faXRlcmF0b3IoSVRFUkFURV9FTlRSSUVTKTtcbiAgICB9LFxuXG4gICAgZXZlcnk6IGZ1bmN0aW9uKHByZWRpY2F0ZSwgY29udGV4dCkge1xuICAgICAgYXNzZXJ0Tm90SW5maW5pdGUodGhpcy5zaXplKTtcbiAgICAgIHZhciByZXR1cm5WYWx1ZSA9IHRydWU7XG4gICAgICB0aGlzLl9faXRlcmF0ZShmdW5jdGlvbih2LCBrLCBjKSAge1xuICAgICAgICBpZiAoIXByZWRpY2F0ZS5jYWxsKGNvbnRleHQsIHYsIGssIGMpKSB7XG4gICAgICAgICAgcmV0dXJuVmFsdWUgPSBmYWxzZTtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICAgIH0sXG5cbiAgICBmaWx0ZXI6IGZ1bmN0aW9uKHByZWRpY2F0ZSwgY29udGV4dCkge1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIGZpbHRlckZhY3RvcnkodGhpcywgcHJlZGljYXRlLCBjb250ZXh0LCB0cnVlKSk7XG4gICAgfSxcblxuICAgIGZpbmQ6IGZ1bmN0aW9uKHByZWRpY2F0ZSwgY29udGV4dCwgbm90U2V0VmFsdWUpIHtcbiAgICAgIHZhciBlbnRyeSA9IHRoaXMuZmluZEVudHJ5KHByZWRpY2F0ZSwgY29udGV4dCk7XG4gICAgICByZXR1cm4gZW50cnkgPyBlbnRyeVsxXSA6IG5vdFNldFZhbHVlO1xuICAgIH0sXG5cbiAgICBmaW5kRW50cnk6IGZ1bmN0aW9uKHByZWRpY2F0ZSwgY29udGV4dCkge1xuICAgICAgdmFyIGZvdW5kO1xuICAgICAgdGhpcy5fX2l0ZXJhdGUoZnVuY3Rpb24odiwgaywgYykgIHtcbiAgICAgICAgaWYgKHByZWRpY2F0ZS5jYWxsKGNvbnRleHQsIHYsIGssIGMpKSB7XG4gICAgICAgICAgZm91bmQgPSBbaywgdl07XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBmb3VuZDtcbiAgICB9LFxuXG4gICAgZmluZExhc3RFbnRyeTogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gdGhpcy50b1NlcSgpLnJldmVyc2UoKS5maW5kRW50cnkocHJlZGljYXRlLCBjb250ZXh0KTtcbiAgICB9LFxuXG4gICAgZm9yRWFjaDogZnVuY3Rpb24oc2lkZUVmZmVjdCwgY29udGV4dCkge1xuICAgICAgYXNzZXJ0Tm90SW5maW5pdGUodGhpcy5zaXplKTtcbiAgICAgIHJldHVybiB0aGlzLl9faXRlcmF0ZShjb250ZXh0ID8gc2lkZUVmZmVjdC5iaW5kKGNvbnRleHQpIDogc2lkZUVmZmVjdCk7XG4gICAgfSxcblxuICAgIGpvaW46IGZ1bmN0aW9uKHNlcGFyYXRvcikge1xuICAgICAgYXNzZXJ0Tm90SW5maW5pdGUodGhpcy5zaXplKTtcbiAgICAgIHNlcGFyYXRvciA9IHNlcGFyYXRvciAhPT0gdW5kZWZpbmVkID8gJycgKyBzZXBhcmF0b3IgOiAnLCc7XG4gICAgICB2YXIgam9pbmVkID0gJyc7XG4gICAgICB2YXIgaXNGaXJzdCA9IHRydWU7XG4gICAgICB0aGlzLl9faXRlcmF0ZShmdW5jdGlvbih2ICkge1xuICAgICAgICBpc0ZpcnN0ID8gKGlzRmlyc3QgPSBmYWxzZSkgOiAoam9pbmVkICs9IHNlcGFyYXRvcik7XG4gICAgICAgIGpvaW5lZCArPSB2ICE9PSBudWxsICYmIHYgIT09IHVuZGVmaW5lZCA/IHYudG9TdHJpbmcoKSA6ICcnO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gam9pbmVkO1xuICAgIH0sXG5cbiAgICBrZXlzOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLl9faXRlcmF0b3IoSVRFUkFURV9LRVlTKTtcbiAgICB9LFxuXG4gICAgbWFwOiBmdW5jdGlvbihtYXBwZXIsIGNvbnRleHQpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCBtYXBGYWN0b3J5KHRoaXMsIG1hcHBlciwgY29udGV4dCkpO1xuICAgIH0sXG5cbiAgICByZWR1Y2U6IGZ1bmN0aW9uKHJlZHVjZXIsIGluaXRpYWxSZWR1Y3Rpb24sIGNvbnRleHQpIHtcbiAgICAgIGFzc2VydE5vdEluZmluaXRlKHRoaXMuc2l6ZSk7XG4gICAgICB2YXIgcmVkdWN0aW9uO1xuICAgICAgdmFyIHVzZUZpcnN0O1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSB7XG4gICAgICAgIHVzZUZpcnN0ID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlZHVjdGlvbiA9IGluaXRpYWxSZWR1Y3Rpb247XG4gICAgICB9XG4gICAgICB0aGlzLl9faXRlcmF0ZShmdW5jdGlvbih2LCBrLCBjKSAge1xuICAgICAgICBpZiAodXNlRmlyc3QpIHtcbiAgICAgICAgICB1c2VGaXJzdCA9IGZhbHNlO1xuICAgICAgICAgIHJlZHVjdGlvbiA9IHY7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVkdWN0aW9uID0gcmVkdWNlci5jYWxsKGNvbnRleHQsIHJlZHVjdGlvbiwgdiwgaywgYyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlZHVjdGlvbjtcbiAgICB9LFxuXG4gICAgcmVkdWNlUmlnaHQ6IGZ1bmN0aW9uKHJlZHVjZXIsIGluaXRpYWxSZWR1Y3Rpb24sIGNvbnRleHQpIHtcbiAgICAgIHZhciByZXZlcnNlZCA9IHRoaXMudG9LZXllZFNlcSgpLnJldmVyc2UoKTtcbiAgICAgIHJldHVybiByZXZlcnNlZC5yZWR1Y2UuYXBwbHkocmV2ZXJzZWQsIGFyZ3VtZW50cyk7XG4gICAgfSxcblxuICAgIHJldmVyc2U6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIHJldmVyc2VGYWN0b3J5KHRoaXMsIHRydWUpKTtcbiAgICB9LFxuXG4gICAgc2xpY2U6IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCBzbGljZUZhY3RvcnkodGhpcywgYmVnaW4sIGVuZCwgdHJ1ZSkpO1xuICAgIH0sXG5cbiAgICBzb21lOiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIHJldHVybiAhdGhpcy5ldmVyeShub3QocHJlZGljYXRlKSwgY29udGV4dCk7XG4gICAgfSxcblxuICAgIHNvcnQ6IGZ1bmN0aW9uKGNvbXBhcmF0b3IpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCBzb3J0RmFjdG9yeSh0aGlzLCBjb21wYXJhdG9yKSk7XG4gICAgfSxcblxuICAgIHZhbHVlczogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fX2l0ZXJhdG9yKElURVJBVEVfVkFMVUVTKTtcbiAgICB9LFxuXG5cbiAgICAvLyAjIyMgTW9yZSBzZXF1ZW50aWFsIG1ldGhvZHNcblxuICAgIGJ1dExhc3Q6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2xpY2UoMCwgLTEpO1xuICAgIH0sXG5cbiAgICBpc0VtcHR5OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLnNpemUgIT09IHVuZGVmaW5lZCA/IHRoaXMuc2l6ZSA9PT0gMCA6ICF0aGlzLnNvbWUoZnVuY3Rpb24oKSAge3JldHVybiB0cnVlfSk7XG4gICAgfSxcblxuICAgIGNvdW50OiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIHJldHVybiBlbnN1cmVTaXplKFxuICAgICAgICBwcmVkaWNhdGUgPyB0aGlzLnRvU2VxKCkuZmlsdGVyKHByZWRpY2F0ZSwgY29udGV4dCkgOiB0aGlzXG4gICAgICApO1xuICAgIH0sXG5cbiAgICBjb3VudEJ5OiBmdW5jdGlvbihncm91cGVyLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gY291bnRCeUZhY3RvcnkodGhpcywgZ3JvdXBlciwgY29udGV4dCk7XG4gICAgfSxcblxuICAgIGVxdWFsczogZnVuY3Rpb24ob3RoZXIpIHtcbiAgICAgIHJldHVybiBkZWVwRXF1YWwodGhpcywgb3RoZXIpO1xuICAgIH0sXG5cbiAgICBlbnRyeVNlcTogZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgaXRlcmFibGUgPSB0aGlzO1xuICAgICAgaWYgKGl0ZXJhYmxlLl9jYWNoZSkge1xuICAgICAgICAvLyBXZSBjYWNoZSBhcyBhbiBlbnRyaWVzIGFycmF5LCBzbyB3ZSBjYW4ganVzdCByZXR1cm4gdGhlIGNhY2hlIVxuICAgICAgICByZXR1cm4gbmV3IEFycmF5U2VxKGl0ZXJhYmxlLl9jYWNoZSk7XG4gICAgICB9XG4gICAgICB2YXIgZW50cmllc1NlcXVlbmNlID0gaXRlcmFibGUudG9TZXEoKS5tYXAoZW50cnlNYXBwZXIpLnRvSW5kZXhlZFNlcSgpO1xuICAgICAgZW50cmllc1NlcXVlbmNlLmZyb21FbnRyeVNlcSA9IGZ1bmN0aW9uKCkgIHtyZXR1cm4gaXRlcmFibGUudG9TZXEoKX07XG4gICAgICByZXR1cm4gZW50cmllc1NlcXVlbmNlO1xuICAgIH0sXG5cbiAgICBmaWx0ZXJOb3Q6IGZ1bmN0aW9uKHByZWRpY2F0ZSwgY29udGV4dCkge1xuICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyKG5vdChwcmVkaWNhdGUpLCBjb250ZXh0KTtcbiAgICB9LFxuXG4gICAgZmluZExhc3Q6IGZ1bmN0aW9uKHByZWRpY2F0ZSwgY29udGV4dCwgbm90U2V0VmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLnRvS2V5ZWRTZXEoKS5yZXZlcnNlKCkuZmluZChwcmVkaWNhdGUsIGNvbnRleHQsIG5vdFNldFZhbHVlKTtcbiAgICB9LFxuXG4gICAgZmlyc3Q6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZmluZChyZXR1cm5UcnVlKTtcbiAgICB9LFxuXG4gICAgZmxhdE1hcDogZnVuY3Rpb24obWFwcGVyLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgZmxhdE1hcEZhY3RvcnkodGhpcywgbWFwcGVyLCBjb250ZXh0KSk7XG4gICAgfSxcblxuICAgIGZsYXR0ZW46IGZ1bmN0aW9uKGRlcHRoKSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgZmxhdHRlbkZhY3RvcnkodGhpcywgZGVwdGgsIHRydWUpKTtcbiAgICB9LFxuXG4gICAgZnJvbUVudHJ5U2VxOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBuZXcgRnJvbUVudHJpZXNTZXF1ZW5jZSh0aGlzKTtcbiAgICB9LFxuXG4gICAgZ2V0OiBmdW5jdGlvbihzZWFyY2hLZXksIG5vdFNldFZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5maW5kKGZ1bmN0aW9uKF8sIGtleSkgIHtyZXR1cm4gaXMoa2V5LCBzZWFyY2hLZXkpfSwgdW5kZWZpbmVkLCBub3RTZXRWYWx1ZSk7XG4gICAgfSxcblxuICAgIGdldEluOiBmdW5jdGlvbihzZWFyY2hLZXlQYXRoLCBub3RTZXRWYWx1ZSkge1xuICAgICAgdmFyIG5lc3RlZCA9IHRoaXM7XG4gICAgICAvLyBOb3RlOiBpbiBhbiBFUzYgZW52aXJvbm1lbnQsIHdlIHdvdWxkIHByZWZlcjpcbiAgICAgIC8vIGZvciAodmFyIGtleSBvZiBzZWFyY2hLZXlQYXRoKSB7XG4gICAgICB2YXIgaXRlciA9IGZvcmNlSXRlcmF0b3Ioc2VhcmNoS2V5UGF0aCk7XG4gICAgICB2YXIgc3RlcDtcbiAgICAgIHdoaWxlICghKHN0ZXAgPSBpdGVyLm5leHQoKSkuZG9uZSkge1xuICAgICAgICB2YXIga2V5ID0gc3RlcC52YWx1ZTtcbiAgICAgICAgbmVzdGVkID0gbmVzdGVkICYmIG5lc3RlZC5nZXQgPyBuZXN0ZWQuZ2V0KGtleSwgTk9UX1NFVCkgOiBOT1RfU0VUO1xuICAgICAgICBpZiAobmVzdGVkID09PSBOT1RfU0VUKSB7XG4gICAgICAgICAgcmV0dXJuIG5vdFNldFZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbmVzdGVkO1xuICAgIH0sXG5cbiAgICBncm91cEJ5OiBmdW5jdGlvbihncm91cGVyLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gZ3JvdXBCeUZhY3RvcnkodGhpcywgZ3JvdXBlciwgY29udGV4dCk7XG4gICAgfSxcblxuICAgIGhhczogZnVuY3Rpb24oc2VhcmNoS2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXQoc2VhcmNoS2V5LCBOT1RfU0VUKSAhPT0gTk9UX1NFVDtcbiAgICB9LFxuXG4gICAgaGFzSW46IGZ1bmN0aW9uKHNlYXJjaEtleVBhdGgpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldEluKHNlYXJjaEtleVBhdGgsIE5PVF9TRVQpICE9PSBOT1RfU0VUO1xuICAgIH0sXG5cbiAgICBpc1N1YnNldDogZnVuY3Rpb24oaXRlcikge1xuICAgICAgaXRlciA9IHR5cGVvZiBpdGVyLmluY2x1ZGVzID09PSAnZnVuY3Rpb24nID8gaXRlciA6IEl0ZXJhYmxlKGl0ZXIpO1xuICAgICAgcmV0dXJuIHRoaXMuZXZlcnkoZnVuY3Rpb24odmFsdWUgKSB7cmV0dXJuIGl0ZXIuaW5jbHVkZXModmFsdWUpfSk7XG4gICAgfSxcblxuICAgIGlzU3VwZXJzZXQ6IGZ1bmN0aW9uKGl0ZXIpIHtcbiAgICAgIGl0ZXIgPSB0eXBlb2YgaXRlci5pc1N1YnNldCA9PT0gJ2Z1bmN0aW9uJyA/IGl0ZXIgOiBJdGVyYWJsZShpdGVyKTtcbiAgICAgIHJldHVybiBpdGVyLmlzU3Vic2V0KHRoaXMpO1xuICAgIH0sXG5cbiAgICBrZXlTZXE6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMudG9TZXEoKS5tYXAoa2V5TWFwcGVyKS50b0luZGV4ZWRTZXEoKTtcbiAgICB9LFxuXG4gICAgbGFzdDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy50b1NlcSgpLnJldmVyc2UoKS5maXJzdCgpO1xuICAgIH0sXG5cbiAgICBtYXg6IGZ1bmN0aW9uKGNvbXBhcmF0b3IpIHtcbiAgICAgIHJldHVybiBtYXhGYWN0b3J5KHRoaXMsIGNvbXBhcmF0b3IpO1xuICAgIH0sXG5cbiAgICBtYXhCeTogZnVuY3Rpb24obWFwcGVyLCBjb21wYXJhdG9yKSB7XG4gICAgICByZXR1cm4gbWF4RmFjdG9yeSh0aGlzLCBjb21wYXJhdG9yLCBtYXBwZXIpO1xuICAgIH0sXG5cbiAgICBtaW46IGZ1bmN0aW9uKGNvbXBhcmF0b3IpIHtcbiAgICAgIHJldHVybiBtYXhGYWN0b3J5KHRoaXMsIGNvbXBhcmF0b3IgPyBuZWcoY29tcGFyYXRvcikgOiBkZWZhdWx0TmVnQ29tcGFyYXRvcik7XG4gICAgfSxcblxuICAgIG1pbkJ5OiBmdW5jdGlvbihtYXBwZXIsIGNvbXBhcmF0b3IpIHtcbiAgICAgIHJldHVybiBtYXhGYWN0b3J5KHRoaXMsIGNvbXBhcmF0b3IgPyBuZWcoY29tcGFyYXRvcikgOiBkZWZhdWx0TmVnQ29tcGFyYXRvciwgbWFwcGVyKTtcbiAgICB9LFxuXG4gICAgcmVzdDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5zbGljZSgxKTtcbiAgICB9LFxuXG4gICAgc2tpcDogZnVuY3Rpb24oYW1vdW50KSB7XG4gICAgICByZXR1cm4gdGhpcy5zbGljZShNYXRoLm1heCgwLCBhbW91bnQpKTtcbiAgICB9LFxuXG4gICAgc2tpcExhc3Q6IGZ1bmN0aW9uKGFtb3VudCkge1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIHRoaXMudG9TZXEoKS5yZXZlcnNlKCkuc2tpcChhbW91bnQpLnJldmVyc2UoKSk7XG4gICAgfSxcblxuICAgIHNraXBXaGlsZTogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgc2tpcFdoaWxlRmFjdG9yeSh0aGlzLCBwcmVkaWNhdGUsIGNvbnRleHQsIHRydWUpKTtcbiAgICB9LFxuXG4gICAgc2tpcFVudGlsOiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIHJldHVybiB0aGlzLnNraXBXaGlsZShub3QocHJlZGljYXRlKSwgY29udGV4dCk7XG4gICAgfSxcblxuICAgIHNvcnRCeTogZnVuY3Rpb24obWFwcGVyLCBjb21wYXJhdG9yKSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgc29ydEZhY3RvcnkodGhpcywgY29tcGFyYXRvciwgbWFwcGVyKSk7XG4gICAgfSxcblxuICAgIHRha2U6IGZ1bmN0aW9uKGFtb3VudCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2xpY2UoMCwgTWF0aC5tYXgoMCwgYW1vdW50KSk7XG4gICAgfSxcblxuICAgIHRha2VMYXN0OiBmdW5jdGlvbihhbW91bnQpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCB0aGlzLnRvU2VxKCkucmV2ZXJzZSgpLnRha2UoYW1vdW50KS5yZXZlcnNlKCkpO1xuICAgIH0sXG5cbiAgICB0YWtlV2hpbGU6IGZ1bmN0aW9uKHByZWRpY2F0ZSwgY29udGV4dCkge1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsIHRha2VXaGlsZUZhY3RvcnkodGhpcywgcHJlZGljYXRlLCBjb250ZXh0KSk7XG4gICAgfSxcblxuICAgIHRha2VVbnRpbDogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gdGhpcy50YWtlV2hpbGUobm90KHByZWRpY2F0ZSksIGNvbnRleHQpO1xuICAgIH0sXG5cbiAgICB2YWx1ZVNlcTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy50b0luZGV4ZWRTZXEoKTtcbiAgICB9LFxuXG5cbiAgICAvLyAjIyMgSGFzaGFibGUgT2JqZWN0XG5cbiAgICBoYXNoQ29kZTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fX2hhc2ggfHwgKHRoaXMuX19oYXNoID0gaGFzaEl0ZXJhYmxlKHRoaXMpKTtcbiAgICB9XG5cblxuICAgIC8vICMjIyBJbnRlcm5hbFxuXG4gICAgLy8gYWJzdHJhY3QgX19pdGVyYXRlKGZuLCByZXZlcnNlKVxuXG4gICAgLy8gYWJzdHJhY3QgX19pdGVyYXRvcih0eXBlLCByZXZlcnNlKVxuICB9KTtcblxuICAvLyB2YXIgSVNfSVRFUkFCTEVfU0VOVElORUwgPSAnQEBfX0lNTVVUQUJMRV9JVEVSQUJMRV9fQEAnO1xuICAvLyB2YXIgSVNfS0VZRURfU0VOVElORUwgPSAnQEBfX0lNTVVUQUJMRV9LRVlFRF9fQEAnO1xuICAvLyB2YXIgSVNfSU5ERVhFRF9TRU5USU5FTCA9ICdAQF9fSU1NVVRBQkxFX0lOREVYRURfX0BAJztcbiAgLy8gdmFyIElTX09SREVSRURfU0VOVElORUwgPSAnQEBfX0lNTVVUQUJMRV9PUkRFUkVEX19AQCc7XG5cbiAgdmFyIEl0ZXJhYmxlUHJvdG90eXBlID0gSXRlcmFibGUucHJvdG90eXBlO1xuICBJdGVyYWJsZVByb3RvdHlwZVtJU19JVEVSQUJMRV9TRU5USU5FTF0gPSB0cnVlO1xuICBJdGVyYWJsZVByb3RvdHlwZVtJVEVSQVRPUl9TWU1CT0xdID0gSXRlcmFibGVQcm90b3R5cGUudmFsdWVzO1xuICBJdGVyYWJsZVByb3RvdHlwZS5fX3RvSlMgPSBJdGVyYWJsZVByb3RvdHlwZS50b0FycmF5O1xuICBJdGVyYWJsZVByb3RvdHlwZS5fX3RvU3RyaW5nTWFwcGVyID0gcXVvdGVTdHJpbmc7XG4gIEl0ZXJhYmxlUHJvdG90eXBlLmluc3BlY3QgPVxuICBJdGVyYWJsZVByb3RvdHlwZS50b1NvdXJjZSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpcy50b1N0cmluZygpOyB9O1xuICBJdGVyYWJsZVByb3RvdHlwZS5jaGFpbiA9IEl0ZXJhYmxlUHJvdG90eXBlLmZsYXRNYXA7XG4gIEl0ZXJhYmxlUHJvdG90eXBlLmNvbnRhaW5zID0gSXRlcmFibGVQcm90b3R5cGUuaW5jbHVkZXM7XG5cbiAgLy8gVGVtcG9yYXJ5IHdhcm5pbmcgYWJvdXQgdXNpbmcgbGVuZ3RoXG4gIChmdW5jdGlvbiAoKSB7XG4gICAgdHJ5IHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShJdGVyYWJsZVByb3RvdHlwZSwgJ2xlbmd0aCcsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaWYgKCFJdGVyYWJsZS5ub0xlbmd0aFdhcm5pbmcpIHtcbiAgICAgICAgICAgIHZhciBzdGFjaztcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgc3RhY2sgPSBlcnJvci5zdGFjaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzdGFjay5pbmRleE9mKCdfd3JhcE9iamVjdCcpID09PSAtMSkge1xuICAgICAgICAgICAgICBjb25zb2xlICYmIGNvbnNvbGUud2FybiAmJiBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgICAgJ2l0ZXJhYmxlLmxlbmd0aCBoYXMgYmVlbiBkZXByZWNhdGVkLCAnK1xuICAgICAgICAgICAgICAgICd1c2UgaXRlcmFibGUuc2l6ZSBvciBpdGVyYWJsZS5jb3VudCgpLiAnK1xuICAgICAgICAgICAgICAgICdUaGlzIHdhcm5pbmcgd2lsbCBiZWNvbWUgYSBzaWxlbnQgZXJyb3IgaW4gYSBmdXR1cmUgdmVyc2lvbi4gJyArXG4gICAgICAgICAgICAgICAgc3RhY2tcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2l6ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHt9XG4gIH0pKCk7XG5cblxuXG4gIG1peGluKEtleWVkSXRlcmFibGUsIHtcblxuICAgIC8vICMjIyBNb3JlIHNlcXVlbnRpYWwgbWV0aG9kc1xuXG4gICAgZmxpcDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgZmxpcEZhY3RvcnkodGhpcykpO1xuICAgIH0sXG5cbiAgICBmaW5kS2V5OiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIHZhciBlbnRyeSA9IHRoaXMuZmluZEVudHJ5KHByZWRpY2F0ZSwgY29udGV4dCk7XG4gICAgICByZXR1cm4gZW50cnkgJiYgZW50cnlbMF07XG4gICAgfSxcblxuICAgIGZpbmRMYXN0S2V5OiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIHJldHVybiB0aGlzLnRvU2VxKCkucmV2ZXJzZSgpLmZpbmRLZXkocHJlZGljYXRlLCBjb250ZXh0KTtcbiAgICB9LFxuXG4gICAga2V5T2Y6IGZ1bmN0aW9uKHNlYXJjaFZhbHVlKSB7XG4gICAgICByZXR1cm4gdGhpcy5maW5kS2V5KGZ1bmN0aW9uKHZhbHVlICkge3JldHVybiBpcyh2YWx1ZSwgc2VhcmNoVmFsdWUpfSk7XG4gICAgfSxcblxuICAgIGxhc3RLZXlPZjogZnVuY3Rpb24oc2VhcmNoVmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmZpbmRMYXN0S2V5KGZ1bmN0aW9uKHZhbHVlICkge3JldHVybiBpcyh2YWx1ZSwgc2VhcmNoVmFsdWUpfSk7XG4gICAgfSxcblxuICAgIG1hcEVudHJpZXM6IGZ1bmN0aW9uKG1hcHBlciwgY29udGV4dCkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsXG4gICAgICAgIHRoaXMudG9TZXEoKS5tYXAoXG4gICAgICAgICAgZnVuY3Rpb24odiwgaykgIHtyZXR1cm4gbWFwcGVyLmNhbGwoY29udGV4dCwgW2ssIHZdLCBpdGVyYXRpb25zKyssIHRoaXMkMCl9XG4gICAgICAgICkuZnJvbUVudHJ5U2VxKClcbiAgICAgICk7XG4gICAgfSxcblxuICAgIG1hcEtleXM6IGZ1bmN0aW9uKG1hcHBlciwgY29udGV4dCkge3ZhciB0aGlzJDAgPSB0aGlzO1xuICAgICAgcmV0dXJuIHJlaWZ5KHRoaXMsXG4gICAgICAgIHRoaXMudG9TZXEoKS5mbGlwKCkubWFwKFxuICAgICAgICAgIGZ1bmN0aW9uKGssIHYpICB7cmV0dXJuIG1hcHBlci5jYWxsKGNvbnRleHQsIGssIHYsIHRoaXMkMCl9XG4gICAgICAgICkuZmxpcCgpXG4gICAgICApO1xuICAgIH1cblxuICB9KTtcblxuICB2YXIgS2V5ZWRJdGVyYWJsZVByb3RvdHlwZSA9IEtleWVkSXRlcmFibGUucHJvdG90eXBlO1xuICBLZXllZEl0ZXJhYmxlUHJvdG90eXBlW0lTX0tFWUVEX1NFTlRJTkVMXSA9IHRydWU7XG4gIEtleWVkSXRlcmFibGVQcm90b3R5cGVbSVRFUkFUT1JfU1lNQk9MXSA9IEl0ZXJhYmxlUHJvdG90eXBlLmVudHJpZXM7XG4gIEtleWVkSXRlcmFibGVQcm90b3R5cGUuX190b0pTID0gSXRlcmFibGVQcm90b3R5cGUudG9PYmplY3Q7XG4gIEtleWVkSXRlcmFibGVQcm90b3R5cGUuX190b1N0cmluZ01hcHBlciA9IGZ1bmN0aW9uKHYsIGspICB7cmV0dXJuIEpTT04uc3RyaW5naWZ5KGspICsgJzogJyArIHF1b3RlU3RyaW5nKHYpfTtcblxuXG5cbiAgbWl4aW4oSW5kZXhlZEl0ZXJhYmxlLCB7XG5cbiAgICAvLyAjIyMgQ29udmVyc2lvbiB0byBvdGhlciB0eXBlc1xuXG4gICAgdG9LZXllZFNlcTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gbmV3IFRvS2V5ZWRTZXF1ZW5jZSh0aGlzLCBmYWxzZSk7XG4gICAgfSxcblxuXG4gICAgLy8gIyMjIEVTNiBDb2xsZWN0aW9uIG1ldGhvZHMgKEVTNiBBcnJheSBhbmQgTWFwKVxuXG4gICAgZmlsdGVyOiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCBmaWx0ZXJGYWN0b3J5KHRoaXMsIHByZWRpY2F0ZSwgY29udGV4dCwgZmFsc2UpKTtcbiAgICB9LFxuXG4gICAgZmluZEluZGV4OiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIHZhciBlbnRyeSA9IHRoaXMuZmluZEVudHJ5KHByZWRpY2F0ZSwgY29udGV4dCk7XG4gICAgICByZXR1cm4gZW50cnkgPyBlbnRyeVswXSA6IC0xO1xuICAgIH0sXG5cbiAgICBpbmRleE9mOiBmdW5jdGlvbihzZWFyY2hWYWx1ZSkge1xuICAgICAgdmFyIGtleSA9IHRoaXMudG9LZXllZFNlcSgpLmtleU9mKHNlYXJjaFZhbHVlKTtcbiAgICAgIHJldHVybiBrZXkgPT09IHVuZGVmaW5lZCA/IC0xIDoga2V5O1xuICAgIH0sXG5cbiAgICBsYXN0SW5kZXhPZjogZnVuY3Rpb24oc2VhcmNoVmFsdWUpIHtcbiAgICAgIHZhciBrZXkgPSB0aGlzLnRvS2V5ZWRTZXEoKS5yZXZlcnNlKCkua2V5T2Yoc2VhcmNoVmFsdWUpO1xuICAgICAgcmV0dXJuIGtleSA9PT0gdW5kZWZpbmVkID8gLTEgOiBrZXk7XG5cbiAgICAgIC8vIHZhciBpbmRleCA9XG4gICAgICAvLyByZXR1cm4gdGhpcy50b1NlcSgpLnJldmVyc2UoKS5pbmRleE9mKHNlYXJjaFZhbHVlKTtcbiAgICB9LFxuXG4gICAgcmV2ZXJzZTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgcmV2ZXJzZUZhY3RvcnkodGhpcywgZmFsc2UpKTtcbiAgICB9LFxuXG4gICAgc2xpY2U6IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCBzbGljZUZhY3RvcnkodGhpcywgYmVnaW4sIGVuZCwgZmFsc2UpKTtcbiAgICB9LFxuXG4gICAgc3BsaWNlOiBmdW5jdGlvbihpbmRleCwgcmVtb3ZlTnVtIC8qLCAuLi52YWx1ZXMqLykge1xuICAgICAgdmFyIG51bUFyZ3MgPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgICAgcmVtb3ZlTnVtID0gTWF0aC5tYXgocmVtb3ZlTnVtIHwgMCwgMCk7XG4gICAgICBpZiAobnVtQXJncyA9PT0gMCB8fCAobnVtQXJncyA9PT0gMiAmJiAhcmVtb3ZlTnVtKSkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIC8vIElmIGluZGV4IGlzIG5lZ2F0aXZlLCBpdCBzaG91bGQgcmVzb2x2ZSByZWxhdGl2ZSB0byB0aGUgc2l6ZSBvZiB0aGVcbiAgICAgIC8vIGNvbGxlY3Rpb24uIEhvd2V2ZXIgc2l6ZSBtYXkgYmUgZXhwZW5zaXZlIHRvIGNvbXB1dGUgaWYgbm90IGNhY2hlZCwgc29cbiAgICAgIC8vIG9ubHkgY2FsbCBjb3VudCgpIGlmIHRoZSBudW1iZXIgaXMgaW4gZmFjdCBuZWdhdGl2ZS5cbiAgICAgIGluZGV4ID0gcmVzb2x2ZUJlZ2luKGluZGV4LCBpbmRleCA8IDAgPyB0aGlzLmNvdW50KCkgOiB0aGlzLnNpemUpO1xuICAgICAgdmFyIHNwbGljZWQgPSB0aGlzLnNsaWNlKDAsIGluZGV4KTtcbiAgICAgIHJldHVybiByZWlmeShcbiAgICAgICAgdGhpcyxcbiAgICAgICAgbnVtQXJncyA9PT0gMSA/XG4gICAgICAgICAgc3BsaWNlZCA6XG4gICAgICAgICAgc3BsaWNlZC5jb25jYXQoYXJyQ29weShhcmd1bWVudHMsIDIpLCB0aGlzLnNsaWNlKGluZGV4ICsgcmVtb3ZlTnVtKSlcbiAgICAgICk7XG4gICAgfSxcblxuXG4gICAgLy8gIyMjIE1vcmUgY29sbGVjdGlvbiBtZXRob2RzXG5cbiAgICBmaW5kTGFzdEluZGV4OiBmdW5jdGlvbihwcmVkaWNhdGUsIGNvbnRleHQpIHtcbiAgICAgIHZhciBrZXkgPSB0aGlzLnRvS2V5ZWRTZXEoKS5maW5kTGFzdEtleShwcmVkaWNhdGUsIGNvbnRleHQpO1xuICAgICAgcmV0dXJuIGtleSA9PT0gdW5kZWZpbmVkID8gLTEgOiBrZXk7XG4gICAgfSxcblxuICAgIGZpcnN0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldCgwKTtcbiAgICB9LFxuXG4gICAgZmxhdHRlbjogZnVuY3Rpb24oZGVwdGgpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCBmbGF0dGVuRmFjdG9yeSh0aGlzLCBkZXB0aCwgZmFsc2UpKTtcbiAgICB9LFxuXG4gICAgZ2V0OiBmdW5jdGlvbihpbmRleCwgbm90U2V0VmFsdWUpIHtcbiAgICAgIGluZGV4ID0gd3JhcEluZGV4KHRoaXMsIGluZGV4KTtcbiAgICAgIHJldHVybiAoaW5kZXggPCAwIHx8ICh0aGlzLnNpemUgPT09IEluZmluaXR5IHx8XG4gICAgICAgICAgKHRoaXMuc2l6ZSAhPT0gdW5kZWZpbmVkICYmIGluZGV4ID4gdGhpcy5zaXplKSkpID9cbiAgICAgICAgbm90U2V0VmFsdWUgOlxuICAgICAgICB0aGlzLmZpbmQoZnVuY3Rpb24oXywga2V5KSAge3JldHVybiBrZXkgPT09IGluZGV4fSwgdW5kZWZpbmVkLCBub3RTZXRWYWx1ZSk7XG4gICAgfSxcblxuICAgIGhhczogZnVuY3Rpb24oaW5kZXgpIHtcbiAgICAgIGluZGV4ID0gd3JhcEluZGV4KHRoaXMsIGluZGV4KTtcbiAgICAgIHJldHVybiBpbmRleCA+PSAwICYmICh0aGlzLnNpemUgIT09IHVuZGVmaW5lZCA/XG4gICAgICAgIHRoaXMuc2l6ZSA9PT0gSW5maW5pdHkgfHwgaW5kZXggPCB0aGlzLnNpemUgOlxuICAgICAgICB0aGlzLmluZGV4T2YoaW5kZXgpICE9PSAtMVxuICAgICAgKTtcbiAgICB9LFxuXG4gICAgaW50ZXJwb3NlOiBmdW5jdGlvbihzZXBhcmF0b3IpIHtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCBpbnRlcnBvc2VGYWN0b3J5KHRoaXMsIHNlcGFyYXRvcikpO1xuICAgIH0sXG5cbiAgICBpbnRlcmxlYXZlOiBmdW5jdGlvbigvKi4uLml0ZXJhYmxlcyovKSB7XG4gICAgICB2YXIgaXRlcmFibGVzID0gW3RoaXNdLmNvbmNhdChhcnJDb3B5KGFyZ3VtZW50cykpO1xuICAgICAgdmFyIHppcHBlZCA9IHppcFdpdGhGYWN0b3J5KHRoaXMudG9TZXEoKSwgSW5kZXhlZFNlcS5vZiwgaXRlcmFibGVzKTtcbiAgICAgIHZhciBpbnRlcmxlYXZlZCA9IHppcHBlZC5mbGF0dGVuKHRydWUpO1xuICAgICAgaWYgKHppcHBlZC5zaXplKSB7XG4gICAgICAgIGludGVybGVhdmVkLnNpemUgPSB6aXBwZWQuc2l6ZSAqIGl0ZXJhYmxlcy5sZW5ndGg7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgaW50ZXJsZWF2ZWQpO1xuICAgIH0sXG5cbiAgICBsYXN0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldCgtMSk7XG4gICAgfSxcblxuICAgIHNraXBXaGlsZTogZnVuY3Rpb24ocHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgc2tpcFdoaWxlRmFjdG9yeSh0aGlzLCBwcmVkaWNhdGUsIGNvbnRleHQsIGZhbHNlKSk7XG4gICAgfSxcblxuICAgIHppcDogZnVuY3Rpb24oLyosIC4uLml0ZXJhYmxlcyAqLykge1xuICAgICAgdmFyIGl0ZXJhYmxlcyA9IFt0aGlzXS5jb25jYXQoYXJyQ29weShhcmd1bWVudHMpKTtcbiAgICAgIHJldHVybiByZWlmeSh0aGlzLCB6aXBXaXRoRmFjdG9yeSh0aGlzLCBkZWZhdWx0WmlwcGVyLCBpdGVyYWJsZXMpKTtcbiAgICB9LFxuXG4gICAgemlwV2l0aDogZnVuY3Rpb24oemlwcGVyLyosIC4uLml0ZXJhYmxlcyAqLykge1xuICAgICAgdmFyIGl0ZXJhYmxlcyA9IGFyckNvcHkoYXJndW1lbnRzKTtcbiAgICAgIGl0ZXJhYmxlc1swXSA9IHRoaXM7XG4gICAgICByZXR1cm4gcmVpZnkodGhpcywgemlwV2l0aEZhY3RvcnkodGhpcywgemlwcGVyLCBpdGVyYWJsZXMpKTtcbiAgICB9XG5cbiAgfSk7XG5cbiAgSW5kZXhlZEl0ZXJhYmxlLnByb3RvdHlwZVtJU19JTkRFWEVEX1NFTlRJTkVMXSA9IHRydWU7XG4gIEluZGV4ZWRJdGVyYWJsZS5wcm90b3R5cGVbSVNfT1JERVJFRF9TRU5USU5FTF0gPSB0cnVlO1xuXG5cblxuICBtaXhpbihTZXRJdGVyYWJsZSwge1xuXG4gICAgLy8gIyMjIEVTNiBDb2xsZWN0aW9uIG1ldGhvZHMgKEVTNiBBcnJheSBhbmQgTWFwKVxuXG4gICAgZ2V0OiBmdW5jdGlvbih2YWx1ZSwgbm90U2V0VmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmhhcyh2YWx1ZSkgPyB2YWx1ZSA6IG5vdFNldFZhbHVlO1xuICAgIH0sXG5cbiAgICBpbmNsdWRlczogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmhhcyh2YWx1ZSk7XG4gICAgfSxcblxuXG4gICAgLy8gIyMjIE1vcmUgc2VxdWVudGlhbCBtZXRob2RzXG5cbiAgICBrZXlTZXE6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMudmFsdWVTZXEoKTtcbiAgICB9XG5cbiAgfSk7XG5cbiAgU2V0SXRlcmFibGUucHJvdG90eXBlLmhhcyA9IEl0ZXJhYmxlUHJvdG90eXBlLmluY2x1ZGVzO1xuXG5cbiAgLy8gTWl4aW4gc3ViY2xhc3Nlc1xuXG4gIG1peGluKEtleWVkU2VxLCBLZXllZEl0ZXJhYmxlLnByb3RvdHlwZSk7XG4gIG1peGluKEluZGV4ZWRTZXEsIEluZGV4ZWRJdGVyYWJsZS5wcm90b3R5cGUpO1xuICBtaXhpbihTZXRTZXEsIFNldEl0ZXJhYmxlLnByb3RvdHlwZSk7XG5cbiAgbWl4aW4oS2V5ZWRDb2xsZWN0aW9uLCBLZXllZEl0ZXJhYmxlLnByb3RvdHlwZSk7XG4gIG1peGluKEluZGV4ZWRDb2xsZWN0aW9uLCBJbmRleGVkSXRlcmFibGUucHJvdG90eXBlKTtcbiAgbWl4aW4oU2V0Q29sbGVjdGlvbiwgU2V0SXRlcmFibGUucHJvdG90eXBlKTtcblxuXG4gIC8vICNwcmFnbWEgSGVscGVyIGZ1bmN0aW9uc1xuXG4gIGZ1bmN0aW9uIGtleU1hcHBlcih2LCBrKSB7XG4gICAgcmV0dXJuIGs7XG4gIH1cblxuICBmdW5jdGlvbiBlbnRyeU1hcHBlcih2LCBrKSB7XG4gICAgcmV0dXJuIFtrLCB2XTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG5vdChwcmVkaWNhdGUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gIXByZWRpY2F0ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG5lZyhwcmVkaWNhdGUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gLXByZWRpY2F0ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHF1b3RlU3RyaW5nKHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgPyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkgOiB2YWx1ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlZmF1bHRaaXBwZXIoKSB7XG4gICAgcmV0dXJuIGFyckNvcHkoYXJndW1lbnRzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlZmF1bHROZWdDb21wYXJhdG9yKGEsIGIpIHtcbiAgICByZXR1cm4gYSA8IGIgPyAxIDogYSA+IGIgPyAtMSA6IDA7XG4gIH1cblxuICBmdW5jdGlvbiBoYXNoSXRlcmFibGUoaXRlcmFibGUpIHtcbiAgICBpZiAoaXRlcmFibGUuc2l6ZSA9PT0gSW5maW5pdHkpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICB2YXIgb3JkZXJlZCA9IGlzT3JkZXJlZChpdGVyYWJsZSk7XG4gICAgdmFyIGtleWVkID0gaXNLZXllZChpdGVyYWJsZSk7XG4gICAgdmFyIGggPSBvcmRlcmVkID8gMSA6IDA7XG4gICAgdmFyIHNpemUgPSBpdGVyYWJsZS5fX2l0ZXJhdGUoXG4gICAgICBrZXllZCA/XG4gICAgICAgIG9yZGVyZWQgP1xuICAgICAgICAgIGZ1bmN0aW9uKHYsIGspICB7IGggPSAzMSAqIGggKyBoYXNoTWVyZ2UoaGFzaCh2KSwgaGFzaChrKSkgfCAwOyB9IDpcbiAgICAgICAgICBmdW5jdGlvbih2LCBrKSAgeyBoID0gaCArIGhhc2hNZXJnZShoYXNoKHYpLCBoYXNoKGspKSB8IDA7IH0gOlxuICAgICAgICBvcmRlcmVkID9cbiAgICAgICAgICBmdW5jdGlvbih2ICkgeyBoID0gMzEgKiBoICsgaGFzaCh2KSB8IDA7IH0gOlxuICAgICAgICAgIGZ1bmN0aW9uKHYgKSB7IGggPSBoICsgaGFzaCh2KSB8IDA7IH1cbiAgICApO1xuICAgIHJldHVybiBtdXJtdXJIYXNoT2ZTaXplKHNpemUsIGgpO1xuICB9XG5cbiAgZnVuY3Rpb24gbXVybXVySGFzaE9mU2l6ZShzaXplLCBoKSB7XG4gICAgaCA9IGltdWwoaCwgMHhDQzlFMkQ1MSk7XG4gICAgaCA9IGltdWwoaCA8PCAxNSB8IGggPj4+IC0xNSwgMHgxQjg3MzU5Myk7XG4gICAgaCA9IGltdWwoaCA8PCAxMyB8IGggPj4+IC0xMywgNSk7XG4gICAgaCA9IChoICsgMHhFNjU0NkI2NCB8IDApIF4gc2l6ZTtcbiAgICBoID0gaW11bChoIF4gaCA+Pj4gMTYsIDB4ODVFQkNBNkIpO1xuICAgIGggPSBpbXVsKGggXiBoID4+PiAxMywgMHhDMkIyQUUzNSk7XG4gICAgaCA9IHNtaShoIF4gaCA+Pj4gMTYpO1xuICAgIHJldHVybiBoO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFzaE1lcmdlKGEsIGIpIHtcbiAgICByZXR1cm4gYSBeIGIgKyAweDlFMzc3OUI5ICsgKGEgPDwgNikgKyAoYSA+PiAyKSB8IDA7IC8vIGludFxuICB9XG5cbiAgdmFyIEltbXV0YWJsZSA9IHtcblxuICAgIEl0ZXJhYmxlOiBJdGVyYWJsZSxcblxuICAgIFNlcTogU2VxLFxuICAgIENvbGxlY3Rpb246IENvbGxlY3Rpb24sXG4gICAgTWFwOiBNYXAsXG4gICAgT3JkZXJlZE1hcDogT3JkZXJlZE1hcCxcbiAgICBMaXN0OiBMaXN0LFxuICAgIFN0YWNrOiBTdGFjayxcbiAgICBTZXQ6IFNldCxcbiAgICBPcmRlcmVkU2V0OiBPcmRlcmVkU2V0LFxuXG4gICAgUmVjb3JkOiBSZWNvcmQsXG4gICAgUmFuZ2U6IFJhbmdlLFxuICAgIFJlcGVhdDogUmVwZWF0LFxuXG4gICAgaXM6IGlzLFxuICAgIGZyb21KUzogZnJvbUpTXG5cbiAgfTtcblxuICByZXR1cm4gSW1tdXRhYmxlO1xuXG59KSk7IiwiLy8gVXRpbGl0eSBwcm90b2NvbCBmb3IgbWVhc3VyaW5nIHdoZW4gYSBzdGF0ZUNoYW5nZSB0YWtlcyBlZmZlY3QuXG5cbnZhciBSYW5kb21JRCA9IHJlcXVpcmUoJy4vcmFuZG9taWQuanMnKTtcbnZhciBEYXRhc3BhY2UgPSByZXF1aXJlKCcuL2RhdGFzcGFjZS5qcycpLkRhdGFzcGFjZTtcbnZhciBSb3V0ZSA9IHJlcXVpcmUoJy4vcm91dGUuanMnKTtcbnZhciBQYXRjaCA9IHJlcXVpcmUoJy4vcGF0Y2guanMnKTtcblxudmFyICRBY2sgPSBuZXcgUm91dGUuJFNwZWNpYWwoJ2FjaycpO1xuXG5mdW5jdGlvbiBBY2sobWV0YUxldmVsLCBpZCkge1xuICB0aGlzLm1ldGFMZXZlbCA9IG1ldGFMZXZlbCB8fCAwO1xuICB0aGlzLmlkID0gaWQgfHwgUmFuZG9tSUQucmFuZG9tSWQoMTYpO1xuICB0aGlzLmRvbmUgPSBmYWxzZTtcbn1cblxuQWNrLnByb3RvdHlwZS5hcm0gPSBmdW5jdGlvbiAoKSB7XG4gIERhdGFzcGFjZS5zdGF0ZUNoYW5nZShQYXRjaC5zdWIoWyRBY2ssIHRoaXMuaWRdLCB0aGlzLm1ldGFMZXZlbCkpO1xuICBEYXRhc3BhY2Uuc2VuZChbJEFjaywgdGhpcy5pZF0sIHRoaXMubWV0YUxldmVsKTtcbn07XG5cbkFjay5wcm90b3R5cGUuZGlzYXJtID0gZnVuY3Rpb24gKCkge1xuICBEYXRhc3BhY2Uuc3RhdGVDaGFuZ2UoUGF0Y2gudW5zdWIoWyRBY2ssIHRoaXMuaWRdLCB0aGlzLm1ldGFMZXZlbCkpO1xufTtcblxuQWNrLnByb3RvdHlwZS5jaGVjayA9IGZ1bmN0aW9uIChlKSB7XG4gIGlmICghdGhpcy5kb25lKSB7XG4gICAgaWYgKGUudHlwZSA9PT0gJ21lc3NhZ2UnKSB7XG4gICAgICB2YXIgbSA9IFBhdGNoLnN0cmlwQXRNZXRhKGUubWVzc2FnZSwgdGhpcy5tZXRhTGV2ZWwpO1xuICAgICAgaWYgKG0gJiYgbVswXSA9PT0gJEFjayAmJiBtWzFdID09PSB0aGlzLmlkKSB7XG5cdHRoaXMuZGlzYXJtKCk7XG5cdHRoaXMuZG9uZSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiB0aGlzLmRvbmU7XG59O1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxubW9kdWxlLmV4cG9ydHMuJEFjayA9ICRBY2s7XG5tb2R1bGUuZXhwb3J0cy5BY2sgPSBBY2s7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBJbW11dGFibGUgPSByZXF1aXJlKCdpbW11dGFibGUnKTtcbnZhciBEYXRhc3BhY2UgPSByZXF1aXJlKCcuL2RhdGFzcGFjZS5qcycpLkRhdGFzcGFjZTtcbnZhciBNdXggPSByZXF1aXJlKCcuL211eC5qcycpO1xudmFyIFBhdGNoID0gcmVxdWlyZSgnLi9wYXRjaC5qcycpO1xudmFyIFJvdXRlID0gcmVxdWlyZSgnLi9yb3V0ZS5qcycpO1xudmFyIFV0aWwgPSByZXF1aXJlKCcuL3V0aWwuanMnKTtcblxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuZnVuY3Rpb24gc3Bhd25BY3RvcihzdGF0ZSwgYm9vdEZuKSB7XG4gIERhdGFzcGFjZS5zcGF3bihuZXcgQWN0b3Ioc3RhdGUsIGJvb3RGbikpO1xufVxuXG5mdW5jdGlvbiBBY3RvcihzdGF0ZSwgYm9vdEZuKSB7XG4gIHRoaXMuc3RhdGUgPSBzdGF0ZTtcbiAgdGhpcy5mYWNldHMgPSBJbW11dGFibGUuU2V0KCk7XG4gIHRoaXMubXV4ID0gbmV3IE11eC5NdXgoKTtcblxuICB0aGlzLmJvb3QgPSBmdW5jdGlvbigpIHtcbiAgICBib290Rm4uY2FsbCh0aGlzLnN0YXRlKTtcbiAgICB0aGlzLmNoZWNrRm9yVGVybWluYXRpb24oKTtcbiAgfTtcbn1cblxuQWN0b3IucHJvdG90eXBlLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24oZSkge1xuICB0aGlzLmZhY2V0cy5mb3JFYWNoKGZ1bmN0aW9uIChmKSB7XG4gICAgZi5oYW5kbGVFdmVudChlKTtcbiAgfSk7XG4gIHRoaXMuY2hlY2tGb3JUZXJtaW5hdGlvbigpO1xufTtcblxuQWN0b3IucHJvdG90eXBlLmFkZEZhY2V0ID0gZnVuY3Rpb24oZmFjZXQpIHtcbiAgdGhpcy5mYWNldHMgPSB0aGlzLmZhY2V0cy5hZGQoZmFjZXQpO1xufTtcblxuQWN0b3IucHJvdG90eXBlLnJlbW92ZUZhY2V0ID0gZnVuY3Rpb24oZmFjZXQpIHtcbiAgdGhpcy5mYWNldHMgPSB0aGlzLmZhY2V0cy5yZW1vdmUoZmFjZXQpO1xufTtcblxuQWN0b3IucHJvdG90eXBlLmNoZWNrRm9yVGVybWluYXRpb24gPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuZmFjZXRzLmlzRW1wdHkoKSkge1xuICAgIERhdGFzcGFjZS5leGl0KCk7XG4gIH1cbn07XG5cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmZ1bmN0aW9uIGNyZWF0ZUZhY2V0KCkge1xuICByZXR1cm4gbmV3IEZhY2V0KERhdGFzcGFjZS5hY3RpdmVCZWhhdmlvcigpKTtcbn1cblxuZnVuY3Rpb24gRmFjZXQoYWN0b3IpIHtcbiAgdGhpcy5hY3RvciA9IGFjdG9yO1xuICB0aGlzLmVuZHBvaW50cyA9IEltbXV0YWJsZS5NYXAoKTtcbiAgdGhpcy5pbml0QmxvY2tzID0gSW1tdXRhYmxlLkxpc3QoKTtcbiAgdGhpcy5kb25lQmxvY2tzID0gSW1tdXRhYmxlLkxpc3QoKTtcbn1cblxuRmFjZXQucHJvdG90eXBlLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24oZSkge1xuICB2YXIgZmFjZXQgPSB0aGlzO1xuICB0aGlzLmVuZHBvaW50cy5mb3JFYWNoKGZ1bmN0aW9uKGVuZHBvaW50KSB7XG4gICAgZW5kcG9pbnQuaGFuZGxlckZuLmNhbGwoZmFjZXQuYWN0b3Iuc3RhdGUsIGUpO1xuICB9KTtcbiAgdGhpcy5yZWZyZXNoKCk7XG59O1xuXG5GYWNldC5wcm90b3R5cGUuYWRkQXNzZXJ0aW9uID0gZnVuY3Rpb24oYXNzZXJ0aW9uRm4pIHtcbiAgcmV0dXJuIHRoaXMuYWRkRW5kcG9pbnQobmV3IEVuZHBvaW50KGFzc2VydGlvbkZuLCBmdW5jdGlvbihlKSB7fSkpO1xufTtcblxuRmFjZXQucHJvdG90eXBlLm9uRXZlbnQgPSBmdW5jdGlvbihpc1Rlcm1pbmFsLCBldmVudFR5cGUsIHN1YnNjcmlwdGlvbkZuLCBwcm9qZWN0aW9uRm4sIGhhbmRsZXJGbikge1xuICB2YXIgZmFjZXQgPSB0aGlzO1xuICBzd2l0Y2ggKGV2ZW50VHlwZSkge1xuXG4gIGNhc2UgJ21lc3NhZ2UnOlxuICAgIHJldHVybiB0aGlzLmFkZEVuZHBvaW50KG5ldyBFbmRwb2ludChzdWJzY3JpcHRpb25GbiwgZnVuY3Rpb24oZSkge1xuICAgICAgaWYgKGUudHlwZSA9PT0gJ21lc3NhZ2UnKSB7XG4gICAgICAgIHZhciBwcm9qID0gcHJvamVjdGlvbkZuLmNhbGwoZmFjZXQuYWN0b3Iuc3RhdGUpO1xuICAgICAgICB2YXIgc3BlYyA9IFBhdGNoLnByZXBlbmRBdE1ldGEocHJvai5hc3NlcnRpb24sIHByb2oubWV0YWxldmVsKTtcbiAgICAgICAgdmFyIG1hdGNoID0gUm91dGUubWF0Y2hQYXR0ZXJuKGUubWVzc2FnZSwgc3BlYyk7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKG1hdGNoKTtcbiAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgaWYgKGlzVGVybWluYWwpIHsgZmFjZXQudGVybWluYXRlKCk7IH1cbiAgICAgICAgICBVdGlsLmt3QXBwbHkoaGFuZGxlckZuLCBmYWNldC5hY3Rvci5zdGF0ZSwgbWF0Y2gpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSkpO1xuXG4gIGNhc2UgJ2Fzc2VydGVkJzogLyogZmFsbCB0aHJvdWdoICovXG4gIGNhc2UgJ3JldHJhY3RlZCc6XG4gICAgcmV0dXJuIHRoaXMuYWRkRW5kcG9pbnQobmV3IEVuZHBvaW50KHN1YnNjcmlwdGlvbkZuLCBmdW5jdGlvbihlKSB7XG4gICAgICBpZiAoZS50eXBlID09PSAnc3RhdGVDaGFuZ2UnKSB7XG4gICAgICAgIHZhciBwcm9qID0gcHJvamVjdGlvbkZuLmNhbGwoZmFjZXQuYWN0b3Iuc3RhdGUpO1xuICAgICAgICB2YXIgc3BlYyA9IFBhdGNoLnByZXBlbmRBdE1ldGEocHJvai5hc3NlcnRpb24sIHByb2oubWV0YWxldmVsKTtcbiAgICAgICAgdmFyIGNvbXBpbGVkU3BlYyA9IFJvdXRlLmNvbXBpbGVQcm9qZWN0aW9uKHNwZWMpO1xuICAgICAgICB2YXIgb2JqZWN0cyA9IFJvdXRlLnByb2plY3RPYmplY3RzKGV2ZW50VHlwZSA9PT0gJ2Fzc2VydGVkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gZS5wYXRjaC5hZGRlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZS5wYXRjaC5yZW1vdmVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBpbGVkU3BlYyk7XG4gICAgICAgIGlmIChvYmplY3RzICYmIG9iamVjdHMuc2l6ZSA+IDApIHtcbiAgICAgICAgICAvLyBjb25zb2xlLmxvZyhvYmplY3RzLnRvQXJyYXkoKSk7XG4gICAgICAgICAgaWYgKGlzVGVybWluYWwpIHsgZmFjZXQudGVybWluYXRlKCk7IH1cbiAgICAgICAgICBvYmplY3RzLmZvckVhY2goZnVuY3Rpb24gKG8pIHsgVXRpbC5rd0FwcGx5KGhhbmRsZXJGbiwgZmFjZXQuYWN0b3Iuc3RhdGUsIG8pOyB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pKTtcblxuICBjYXNlICdyaXNpbmdFZGdlJzpcbiAgICB2YXIgZW5kcG9pbnQgPSBuZXcgRW5kcG9pbnQoZnVuY3Rpb24oKSB7IHJldHVybiBQYXRjaC5lbXB0eVBhdGNoOyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld1ZhbHVlID0gc3Vic2NyaXB0aW9uRm4uY2FsbChmYWNldC5hY3Rvci5zdGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld1ZhbHVlICYmICF0aGlzLmN1cnJlbnRWYWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzVGVybWluYWwpIHsgZmFjZXQudGVybWluYXRlKCk7IH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXJGbi5jYWxsKGZhY2V0LmFjdG9yLnN0YXRlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50VmFsdWUgPSBuZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgZW5kcG9pbnQuY3VycmVudFZhbHVlID0gZmFsc2U7XG4gICAgcmV0dXJuIHRoaXMuYWRkRW5kcG9pbnQoZW5kcG9pbnQpO1xuXG4gIGRlZmF1bHQ6XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgRmFjZXQgZXZlbnRUeXBlOiBcIiArIGV2ZW50VHlwZSk7XG4gIH1cbn07XG5cbkZhY2V0LnByb3RvdHlwZS5hZGRFbmRwb2ludCA9IGZ1bmN0aW9uKGVuZHBvaW50KSB7XG4gIHZhciBwYXRjaCA9IGVuZHBvaW50LnN1YnNjcmlwdGlvbkZuLmNhbGwodGhpcy5hY3Rvci5zdGF0ZSk7XG4gIHZhciByID0gdGhpcy5hY3Rvci5tdXguYWRkU3RyZWFtKHBhdGNoKTtcbiAgdGhpcy5lbmRwb2ludHMgPSB0aGlzLmVuZHBvaW50cy5zZXQoci5waWQsIGVuZHBvaW50KTtcbiAgRGF0YXNwYWNlLnN0YXRlQ2hhbmdlKHIuZGVsdGFBZ2dyZWdhdGUpO1xuICByZXR1cm4gdGhpczsgLy8gZm9yIGNoYWluaW5nXG59O1xuXG5GYWNldC5wcm90b3R5cGUuYWRkSW5pdEJsb2NrID0gZnVuY3Rpb24odGh1bmspIHtcbiAgdGhpcy5pbml0QmxvY2tzID0gdGhpcy5pbml0QmxvY2tzLnB1c2godGh1bmspO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkZhY2V0LnByb3RvdHlwZS5hZGREb25lQmxvY2sgPSBmdW5jdGlvbih0aHVuaykge1xuICB0aGlzLmRvbmVCbG9ja3MgPSB0aGlzLmRvbmVCbG9ja3MucHVzaCh0aHVuayk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuRmFjZXQucHJvdG90eXBlLnJlZnJlc2ggPSBmdW5jdGlvbigpIHtcbiAgdmFyIGZhY2V0ID0gdGhpcztcbiAgdmFyIGFnZ3JlZ2F0ZSA9IFBhdGNoLmVtcHR5UGF0Y2g7XG4gIHRoaXMuZW5kcG9pbnRzLmZvckVhY2goZnVuY3Rpb24oZW5kcG9pbnQsIGVpZCkge1xuICAgIHZhciBwYXRjaCA9XG4gICAgICAgIFBhdGNoLnJldHJhY3QoU3luZGljYXRlLl9fKS5hbmRUaGVuKGVuZHBvaW50LnN1YnNjcmlwdGlvbkZuLmNhbGwoZmFjZXQuYWN0b3Iuc3RhdGUpKTtcbiAgICB2YXIgciA9IGZhY2V0LmFjdG9yLm11eC51cGRhdGVTdHJlYW0oZWlkLCBwYXRjaCk7XG4gICAgYWdncmVnYXRlID0gYWdncmVnYXRlLmFuZFRoZW4oci5kZWx0YUFnZ3JlZ2F0ZSk7XG4gIH0pO1xuICBEYXRhc3BhY2Uuc3RhdGVDaGFuZ2UoYWdncmVnYXRlKTtcbn07XG5cbkZhY2V0LnByb3RvdHlwZS5jb21wbGV0ZUJ1aWxkID0gZnVuY3Rpb24oKSB7XG4gIHZhciBmYWNldCA9IHRoaXM7XG4gIHRoaXMuYWN0b3IuYWRkRmFjZXQodGhpcyk7XG4gIHRoaXMuaW5pdEJsb2Nrcy5mb3JFYWNoKGZ1bmN0aW9uKGIpIHsgYi5jYWxsKGZhY2V0LmFjdG9yLnN0YXRlKTsgfSk7XG59O1xuXG5GYWNldC5wcm90b3R5cGUudGVybWluYXRlID0gZnVuY3Rpb24oKSB7XG4gIHZhciBmYWNldCA9IHRoaXM7XG4gIHZhciBhZ2dyZWdhdGUgPSBQYXRjaC5lbXB0eVBhdGNoO1xuICB0aGlzLmVuZHBvaW50cy5mb3JFYWNoKGZ1bmN0aW9uKGVuZHBvaW50LCBlaWQpIHtcbiAgICB2YXIgciA9IGZhY2V0LmFjdG9yLm11eC5yZW1vdmVTdHJlYW0oZWlkKTtcbiAgICBhZ2dyZWdhdGUgPSBhZ2dyZWdhdGUuYW5kVGhlbihyLmRlbHRhQWdncmVnYXRlKTtcbiAgfSk7XG4gIERhdGFzcGFjZS5zdGF0ZUNoYW5nZShhZ2dyZWdhdGUpO1xuICB0aGlzLmVuZHBvaW50cyA9IEltbXV0YWJsZS5NYXAoKTtcbiAgdGhpcy5hY3Rvci5yZW1vdmVGYWNldCh0aGlzKTtcbiAgdGhpcy5kb25lQmxvY2tzLmZvckVhY2goZnVuY3Rpb24oYikgeyBiLmNhbGwoZmFjZXQuYWN0b3Iuc3RhdGUpOyB9KTtcbn07XG5cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmZ1bmN0aW9uIEVuZHBvaW50KHN1YnNjcmlwdGlvbkZuLCBoYW5kbGVyRm4pIHtcbiAgdGhpcy5zdWJzY3JpcHRpb25GbiA9IHN1YnNjcmlwdGlvbkZuO1xuICB0aGlzLmhhbmRsZXJGbiA9IGhhbmRsZXJGbjtcbn1cblxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxubW9kdWxlLmV4cG9ydHMuc3Bhd25BY3RvciA9IHNwYXduQWN0b3I7XG5tb2R1bGUuZXhwb3J0cy5jcmVhdGVGYWNldCA9IGNyZWF0ZUZhY2V0O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBJbW11dGFibGUgPSByZXF1aXJlKCdpbW11dGFibGUnKTtcbnZhciBSb3V0ZSA9IHJlcXVpcmUoJy4vcm91dGUuanMnKTtcbnZhciBQYXRjaCA9IHJlcXVpcmUoJy4vcGF0Y2guanMnKTtcbnZhciBNdXggPSByZXF1aXJlKCcuL211eC5qcycpO1xuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG4vKiBFdmVudHMgYW5kIEFjdGlvbnMgKi9cblxuZnVuY3Rpb24gc3RhdGVDaGFuZ2UocGF0Y2gpIHtcbiAgcmV0dXJuIHsgdHlwZTogJ3N0YXRlQ2hhbmdlJywgcGF0Y2g6IHBhdGNoIH07XG59XG5cbmZ1bmN0aW9uIG1lc3NhZ2UoYm9keSkge1xuICByZXR1cm4geyB0eXBlOiAnbWVzc2FnZScsIG1lc3NhZ2U6IGJvZHkgfTtcbn1cblxuZnVuY3Rpb24gc3Bhd24oYmVoYXZpb3IpIHtcbiAgcmV0dXJuIHsgdHlwZTogJ3NwYXduJywgYmVoYXZpb3I6IGJlaGF2aW9yIH07XG59XG5cbmZ1bmN0aW9uIHRlcm1pbmF0ZSgpIHtcbiAgcmV0dXJuIHsgdHlwZTogJ3Rlcm1pbmF0ZScgfTtcbn1cblxuZnVuY3Rpb24gdGVybWluYXRlRGF0YXNwYWNlKCkge1xuICByZXR1cm4geyB0eXBlOiAndGVybWluYXRlRGF0YXNwYWNlJyB9O1xufVxuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG4vKiBEYXRhc3BhY2UgKi9cblxuZnVuY3Rpb24gRGF0YXNwYWNlKGJvb3RGbikge1xuICB0aGlzLnBlbmRpbmdBY3Rpb25zID0gSW1tdXRhYmxlLkxpc3QoKTsgLy8gb2YgW3BpZCwgQWN0aW9uXVxuICB0aGlzLnByb2Nlc3NUYWJsZSA9IEltbXV0YWJsZS5NYXAoKTsgLy8gcGlkIC0+IEJlaGF2aW9yXG4gIHRoaXMucnVubmFibGVQaWRzID0gSW1tdXRhYmxlLlNldCgpOyAvLyBvZiBwaWRcbiAgdGhpcy5tdXggPSBuZXcgTXV4Lk11eCgpO1xuICB0aGlzLm9uU3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAobXV4LCBkZWx0YUFnZ3JlZ2F0ZSkge307XG4gIHRoaXMuYXNDaGlsZCgnbWV0YScsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJvb3RGbigpIH0sIHRydWUpO1xufVxuXG4vLyBDbGFzcyBzdGF0ZSBhbmQgbWV0aG9kc1xuXG5EYXRhc3BhY2Uuc3RhY2sgPSBJbW11dGFibGUuTGlzdCgpO1xuXG5EYXRhc3BhY2UuY3VycmVudCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIERhdGFzcGFjZS5zdGFjay5sYXN0KCkuZGF0YXNwYWNlO1xufTtcblxuRGF0YXNwYWNlLmFjdGl2ZVBpZCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIERhdGFzcGFjZS5zdGFjay5sYXN0KCkuYWN0aXZlUGlkO1xufTtcblxuRGF0YXNwYWNlLmFjdGl2ZUJlaGF2aW9yID0gZnVuY3Rpb24gKCkge1xuICB2YXIgZW50cnkgPSBEYXRhc3BhY2Uuc3RhY2subGFzdCgpO1xuICB2YXIgcCA9IGVudHJ5LmRhdGFzcGFjZS5wcm9jZXNzVGFibGUuZ2V0KGVudHJ5LmFjdGl2ZVBpZCk7XG4gIHJldHVybiBwID8gcC5iZWhhdmlvciA6IG51bGw7XG59O1xuXG5EYXRhc3BhY2Uud2l0aERhdGFzcGFjZVN0YWNrID0gZnVuY3Rpb24gKHN0YWNrLCBmKSB7XG4gIHZhciBvbGRTdGFjayA9IERhdGFzcGFjZS5zdGFjaztcbiAgRGF0YXNwYWNlLnN0YWNrID0gc3RhY2s7XG4gIHZhciByZXN1bHQ7XG4gIHRyeSB7XG4gICAgcmVzdWx0ID0gZigpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgRGF0YXNwYWNlLnN0YWNrID0gb2xkU3RhY2s7XG4gICAgdGhyb3cgZTtcbiAgfVxuICBEYXRhc3BhY2Uuc3RhY2sgPSBvbGRTdGFjaztcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbkRhdGFzcGFjZS53cmFwID0gZnVuY3Rpb24gKGYpIHtcbiAgdmFyIHNhdmVkU3RhY2sgPSBEYXRhc3BhY2Uuc3RhY2s7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGFjdHVhbHMgPSBhcmd1bWVudHM7XG4gICAgcmV0dXJuIERhdGFzcGFjZS53aXRoRGF0YXNwYWNlU3RhY2soc2F2ZWRTdGFjaywgZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIHJlc3VsdCA9IERhdGFzcGFjZS5jdXJyZW50KCkuYXNDaGlsZChEYXRhc3BhY2UuYWN0aXZlUGlkKCksIGZ1bmN0aW9uICgpIHtcblx0cmV0dXJuIGYuYXBwbHkobnVsbCwgYWN0dWFscyk7XG4gICAgICB9KTtcbiAgICAgIERhdGFzcGFjZS5zdGFjay5yZXZlcnNlKCkuZm9yRWFjaChmdW5jdGlvbiAoZW50cnkpIHtcblx0ZW50cnkuZGF0YXNwYWNlLm1hcmtSdW5uYWJsZShlbnRyeS5hY3RpdmVQaWQpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuICB9O1xufTtcblxuRGF0YXNwYWNlLmVucXVldWVBY3Rpb24gPSBmdW5jdGlvbiAoYWN0aW9uKSB7XG4gIHZhciBlbnRyeSA9IERhdGFzcGFjZS5zdGFjay5sYXN0KCk7XG4gIGVudHJ5LmRhdGFzcGFjZS5lbnF1ZXVlQWN0aW9uKGVudHJ5LmFjdGl2ZVBpZCwgYWN0aW9uKTtcbn07XG5cbkRhdGFzcGFjZS5zZW5kID0gZnVuY3Rpb24gKGJvZHksIG1ldGFMZXZlbCkge1xuICBEYXRhc3BhY2UuZW5xdWV1ZUFjdGlvbihtZXNzYWdlKFBhdGNoLnByZXBlbmRBdE1ldGEoYm9keSwgbWV0YUxldmVsIHx8IDApKSk7XG59O1xuXG5EYXRhc3BhY2Uuc3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAocGF0Y2gpIHtcbiAgRGF0YXNwYWNlLmVucXVldWVBY3Rpb24oc3RhdGVDaGFuZ2UocGF0Y2gpKTtcbn07XG5cbkRhdGFzcGFjZS5zcGF3biA9IGZ1bmN0aW9uIChiZWhhdmlvcikge1xuICBEYXRhc3BhY2UuZW5xdWV1ZUFjdGlvbihzcGF3bihiZWhhdmlvcikpO1xufTtcblxuRGF0YXNwYWNlLmV4aXQgPSBmdW5jdGlvbiAoZXhuKSB7XG4gIERhdGFzcGFjZS5jdXJyZW50KCkua2lsbChEYXRhc3BhY2UuYWN0aXZlUGlkKCksIGV4bik7XG59O1xuXG5EYXRhc3BhY2UuZXhpdERhdGFzcGFjZSA9IGZ1bmN0aW9uICgpIHtcbiAgRGF0YXNwYWNlLmVucXVldWVBY3Rpb24odGVybWluYXRlRGF0YXNwYWNlKCkpO1xufTtcblxuRGF0YXNwYWNlLmluZXJ0QmVoYXZpb3IgPSB7XG4gIGhhbmRsZUV2ZW50OiBmdW5jdGlvbiAoZSkge31cbn07XG5cbi8vIEluc3RhbmNlIG1ldGhvZHNcblxuRGF0YXNwYWNlLnByb3RvdHlwZS5hc0NoaWxkID0gZnVuY3Rpb24gKHBpZCwgZiwgb21pdExpdmVuZXNzQ2hlY2spIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgcCA9IHRoaXMucHJvY2Vzc1RhYmxlLmdldChwaWQsIG51bGwpO1xuICBpZiAoIW9taXRMaXZlbmVzc0NoZWNrICYmIChwID09PSBudWxsKSkge1xuICAgIGNvbnNvbGUud2FybihcIkRhdGFzcGFjZS5hc0NoaWxkIGVsaWRpbmcgaW52b2NhdGlvbiBvZiBkZWFkIHByb2Nlc3NcIiwgcGlkKTtcbiAgICByZXR1cm47XG4gIH1cblxuICByZXR1cm4gRGF0YXNwYWNlLndpdGhEYXRhc3BhY2VTdGFjayhcbiAgICBEYXRhc3BhY2Uuc3RhY2sucHVzaCh7IGRhdGFzcGFjZTogdGhpcywgYWN0aXZlUGlkOiBwaWQgfSksXG4gICAgZnVuY3Rpb24gKCkge1xuICAgICAgdHJ5IHtcblx0cmV0dXJuIGYocCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG5cdHNlbGYua2lsbChwaWQsIGUpO1xuICAgICAgfVxuICAgIH0pO1xufTtcblxuRGF0YXNwYWNlLnByb3RvdHlwZS5raWxsID0gZnVuY3Rpb24gKHBpZCwgZXhuKSB7XG4gIGlmIChleG4gJiYgZXhuLnN0YWNrKSB7XG4gICAgY29uc29sZS5sb2coXCJQcm9jZXNzIGV4aXRpbmdcIiwgcGlkLCBleG4sIGV4bi5zdGFjayk7XG4gIH0gZWxzZSB7XG4gICAgY29uc29sZS5sb2coXCJQcm9jZXNzIGV4aXRpbmdcIiwgcGlkLCBleG4pO1xuICB9XG4gIHZhciBwID0gdGhpcy5wcm9jZXNzVGFibGUuZ2V0KHBpZCk7XG4gIHRoaXMucHJvY2Vzc1RhYmxlID0gdGhpcy5wcm9jZXNzVGFibGUuc2V0KHBpZCwgeyBiZWhhdmlvcjogRGF0YXNwYWNlLmluZXJ0QmVoYXZpb3IgfSk7XG4gIGlmIChwKSB7XG4gICAgaWYgKHAuYmVoYXZpb3IudHJhcGV4aXQpIHtcbiAgICAgIHRoaXMuYXNDaGlsZChwaWQsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHAuYmVoYXZpb3IudHJhcGV4aXQoZXhuKTsgfSwgdHJ1ZSk7XG4gICAgfVxuICAgIHRoaXMuZW5xdWV1ZUFjdGlvbihwaWQsIHRlcm1pbmF0ZSgpKTtcbiAgfVxufTtcblxuRGF0YXNwYWNlLnByb3RvdHlwZS5ib290ID0gZnVuY3Rpb24gKCkge1xuICAvLyBOZWVkZWQgaW4gb3JkZXIgZm9yIGEgbmV3IERhdGFzcGFjZSB0byBiZSBtYXJrZWQgYXMgXCJydW5uYWJsZVwiLCBzb1xuICAvLyBpdHMgaW5pdGlhbCBhY3Rpb25zIGdldCBwZXJmb3JtZWQuXG59O1xuXG5EYXRhc3BhY2UucHJvdG90eXBlLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24gKGUpIHtcbiAgc3dpdGNoIChlLnR5cGUpIHtcbiAgY2FzZSAnc3RhdGVDaGFuZ2UnOlxuICAgIHRoaXMuZW5xdWV1ZUFjdGlvbignbWV0YScsIHN0YXRlQ2hhbmdlKGUucGF0Y2gubGlmdCgpKSk7XG4gICAgYnJlYWs7XG4gIGNhc2UgJ21lc3NhZ2UnOlxuICAgIHRoaXMuZW5xdWV1ZUFjdGlvbignbWV0YScsIG1lc3NhZ2UoUGF0Y2guYXRNZXRhKGUubWVzc2FnZSkpKTtcbiAgICBicmVhaztcbiAgZGVmYXVsdDpcbiAgICB2YXIgZXhuID0gbmV3IEVycm9yKFwiRXZlbnQgdHlwZSBcIiArIGUudHlwZSArIFwiIG5vdCB1bmRlcnN0b29kXCIpO1xuICAgIGV4bi5ldmVudCA9IGU7XG4gICAgdGhyb3cgZXhuO1xuICB9XG4gIHJldHVybiB0cnVlO1xufTtcblxuRGF0YXNwYWNlLnByb3RvdHlwZS5zdGVwID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5kaXNwYXRjaEFjdGlvbnMoKVxuICAgICYmIHRoaXMucnVuUnVubmFibGVQaWRzKClcbiAgICAmJiAoKHRoaXMucGVuZGluZ0FjdGlvbnMuc2l6ZSA+IDApIHx8ICh0aGlzLnJ1bm5hYmxlUGlkcy5zaXplID4gMCkpO1xufTtcblxuRGF0YXNwYWNlLnByb3RvdHlwZS5lbnF1ZXVlQWN0aW9uID0gZnVuY3Rpb24gKHBpZCwgYWN0aW9uKSB7XG4gIHRoaXMucGVuZGluZ0FjdGlvbnMgPSB0aGlzLnBlbmRpbmdBY3Rpb25zLnB1c2goW3BpZCwgYWN0aW9uXSk7XG59O1xuXG5EYXRhc3BhY2UucHJvdG90eXBlLmRpc3BhdGNoQWN0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgYWN0aW9uUXVldWUgPSB0aGlzLnBlbmRpbmdBY3Rpb25zO1xuICB0aGlzLnBlbmRpbmdBY3Rpb25zID0gSW1tdXRhYmxlLkxpc3QoKTtcbiAgdmFyIGFsaXZlID0gdHJ1ZTtcbiAgYWN0aW9uUXVldWUuZm9yRWFjaChmdW5jdGlvbiAoZW50cnkpIHtcbiAgICB2YXIgcGlkID0gZW50cnlbMF07XG4gICAgdmFyIGFjdGlvbiA9IGVudHJ5WzFdO1xuICAgIGlmICghc2VsZi5pbnRlcnByZXRBY3Rpb24ocGlkLCBhY3Rpb24pKSB7XG4gICAgICBhbGl2ZSA9IGZhbHNlO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBhbGl2ZTtcbn07XG5cbkRhdGFzcGFjZS5wcm90b3R5cGUubWFya1J1bm5hYmxlID0gZnVuY3Rpb24gKHBpZCkge1xuICB0aGlzLnJ1bm5hYmxlUGlkcyA9IHRoaXMucnVubmFibGVQaWRzLmFkZChwaWQpO1xufTtcblxuRGF0YXNwYWNlLnByb3RvdHlwZS5ydW5SdW5uYWJsZVBpZHMgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHBpZFNldCA9IHRoaXMucnVubmFibGVQaWRzO1xuICB0aGlzLnJ1bm5hYmxlUGlkcyA9IEltbXV0YWJsZS5TZXQoKTtcbiAgcGlkU2V0LmZvckVhY2goZnVuY3Rpb24gKHBpZCkge1xuICAgIHZhciBjaGlsZEJ1c3kgPSBzZWxmLmFzQ2hpbGQocGlkLCBmdW5jdGlvbiAocCkge1xuICAgICAgcmV0dXJuIHAuYmVoYXZpb3Iuc3RlcCAvLyBleGlzdHMsIGhhdmVuJ3QgY2FsbGVkIGl0IHlldFxuXHQmJiBwLmJlaGF2aW9yLnN0ZXAoKTtcbiAgICB9KTtcbiAgICBpZiAoY2hpbGRCdXN5KSBzZWxmLm1hcmtSdW5uYWJsZShwaWQpO1xuICB9KTtcbiAgcmV0dXJuIHRydWU7XG59O1xuXG5EYXRhc3BhY2UucHJvdG90eXBlLmludGVycHJldEFjdGlvbiA9IGZ1bmN0aW9uIChwaWQsIGFjdGlvbikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICBjYXNlICdzdGF0ZUNoYW5nZSc6XG4gICAgdmFyIG9sZE11eCA9IHRoaXMubXV4LnNoYWxsb3dDb3B5KCk7XG4gICAgdGhpcy5kZWxpdmVyUGF0Y2hlcyhvbGRNdXgsIHRoaXMubXV4LnVwZGF0ZVN0cmVhbShwaWQsIGFjdGlvbi5wYXRjaCkpO1xuICAgIHJldHVybiB0cnVlO1xuXG4gIGNhc2UgJ21lc3NhZ2UnOlxuICAgIGlmIChQYXRjaC5pc09ic2VydmUoYWN0aW9uLm1lc3NhZ2UpKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1Byb2Nlc3MgJyArIHBpZCArICcgc2VuZCBtZXNzYWdlIGNvbnRhaW5pbmcgcXVlcnknLCBhY3Rpb24ubWVzc2FnZSk7XG4gICAgfVxuICAgIGlmIChwaWQgIT09ICdtZXRhJyAmJiBQYXRjaC5pc0F0TWV0YShhY3Rpb24ubWVzc2FnZSkpIHtcbiAgICAgIERhdGFzcGFjZS5zZW5kKGFjdGlvbi5tZXNzYWdlWzFdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5tdXgucm91dGVNZXNzYWdlKGFjdGlvbi5tZXNzYWdlKS5mb3JFYWNoKGZ1bmN0aW9uIChwaWQpIHtcblx0c2VsZi5kZWxpdmVyRXZlbnQocGlkLCBhY3Rpb24pO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuXG4gIGNhc2UgJ3NwYXduJzpcbiAgICB2YXIgb2xkTXV4ID0gdGhpcy5tdXguc2hhbGxvd0NvcHkoKTtcbiAgICB2YXIgcCA9IHsgYmVoYXZpb3I6IGFjdGlvbi5iZWhhdmlvciB9O1xuICAgIHZhciBwaWQgPSB0aGlzLm11eC5uZXh0UGlkO1xuICAgIHRoaXMucHJvY2Vzc1RhYmxlID0gdGhpcy5wcm9jZXNzVGFibGUuc2V0KHBpZCwgcCk7XG4gICAgdmFyIGluaXRpYWxQYXRjaCA9IFBhdGNoLmVtcHR5UGF0Y2g7XG4gICAgaWYgKHAuYmVoYXZpb3IuYm9vdCkge1xuICAgICAgaW5pdGlhbFBhdGNoID0gdGhpcy5hc0NoaWxkKHBpZCwgZnVuY3Rpb24gKCkgeyByZXR1cm4gcC5iZWhhdmlvci5ib290KCkgfSk7XG4gICAgICBpbml0aWFsUGF0Y2ggPSBpbml0aWFsUGF0Y2ggfHwgUGF0Y2guZW1wdHlQYXRjaDtcbiAgICAgIHRoaXMubWFya1J1bm5hYmxlKHBpZCk7XG4gICAgfVxuICAgIHRoaXMuZGVsaXZlclBhdGNoZXMob2xkTXV4LCB0aGlzLm11eC5hZGRTdHJlYW0oaW5pdGlhbFBhdGNoKSk7XG4gICAgcmV0dXJuIHRydWU7XG5cbiAgY2FzZSAndGVybWluYXRlJzpcbiAgICB2YXIgb2xkTXV4ID0gdGhpcy5tdXguc2hhbGxvd0NvcHkoKTtcbiAgICB0aGlzLmRlbGl2ZXJQYXRjaGVzKG9sZE11eCwgdGhpcy5tdXgucmVtb3ZlU3RyZWFtKHBpZCkpO1xuICAgIGNvbnNvbGUubG9nKFwiUHJvY2VzcyBleGl0IGNvbXBsZXRlXCIsIHBpZCk7XG4gICAgdGhpcy5wcm9jZXNzVGFibGUgPSB0aGlzLnByb2Nlc3NUYWJsZS5yZW1vdmUocGlkKTtcbiAgICByZXR1cm4gdHJ1ZTtcblxuICBjYXNlICd0ZXJtaW5hdGVEYXRhc3BhY2UnOlxuICAgIERhdGFzcGFjZS5leGl0KCk7XG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIGRlZmF1bHQ6XG4gICAgdmFyIGV4biA9IG5ldyBFcnJvcihcIkFjdGlvbiB0eXBlIFwiICsgYWN0aW9uLnR5cGUgKyBcIiBub3QgdW5kZXJzdG9vZFwiKTtcbiAgICBleG4uYWN0aW9uID0gYWN0aW9uO1xuICAgIHRocm93IGV4bjtcbiAgfVxufTtcblxuRGF0YXNwYWNlLnByb3RvdHlwZS5kZWxpdmVyUGF0Y2hlcyA9IGZ1bmN0aW9uIChvbGRNdXgsIHVwZGF0ZVN0cmVhbVJlc3VsdCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBldmVudHMgPSBNdXguY29tcHV0ZUV2ZW50cyhvbGRNdXgsIHRoaXMubXV4LCB1cGRhdGVTdHJlYW1SZXN1bHQpO1xuICBldmVudHMuZXZlbnRNYXAuZm9yRWFjaChmdW5jdGlvbiAocGF0Y2gsIHBpZCkge1xuICAgIHNlbGYuZGVsaXZlckV2ZW50KHBpZCwgc3RhdGVDaGFuZ2UocGF0Y2gpKTtcbiAgfSk7XG4gIGV2ZW50cy5tZXRhRXZlbnRzLmZvckVhY2goRGF0YXNwYWNlLnN0YXRlQ2hhbmdlKTtcbiAgdGhpcy5vblN0YXRlQ2hhbmdlKHRoaXMubXV4LCB1cGRhdGVTdHJlYW1SZXN1bHQuZGVsdGFBZ2dyZWdhdGUpO1xufTtcblxuRGF0YXNwYWNlLnByb3RvdHlwZS5kZWxpdmVyRXZlbnQgPSBmdW5jdGlvbiAocGlkLCBldmVudCkge1xuICB2YXIgY2hpbGRCdXN5ID0gdGhpcy5hc0NoaWxkKHBpZCwgZnVuY3Rpb24gKHApIHsgcmV0dXJuIHAuYmVoYXZpb3IuaGFuZGxlRXZlbnQoZXZlbnQpOyB9KTtcbiAgaWYgKGNoaWxkQnVzeSkgdGhpcy5tYXJrUnVubmFibGUocGlkKTtcbn07XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5tb2R1bGUuZXhwb3J0cy5zdGF0ZUNoYW5nZSA9IHN0YXRlQ2hhbmdlO1xubW9kdWxlLmV4cG9ydHMubWVzc2FnZSA9IG1lc3NhZ2U7XG5tb2R1bGUuZXhwb3J0cy5zcGF3biA9IHNwYXduO1xubW9kdWxlLmV4cG9ydHMudGVybWluYXRlID0gdGVybWluYXRlO1xubW9kdWxlLmV4cG9ydHMudGVybWluYXRlRGF0YXNwYWNlID0gdGVybWluYXRlRGF0YXNwYWNlO1xuXG5tb2R1bGUuZXhwb3J0cy5EYXRhc3BhY2UgPSBEYXRhc3BhY2U7XG4iLCJ2YXIgSW1tdXRhYmxlID0gcmVxdWlyZSgnaW1tdXRhYmxlJyk7XG52YXIgUm91dGUgPSByZXF1aXJlKCcuL3JvdXRlLmpzJyk7XG52YXIgUGF0Y2ggPSByZXF1aXJlKCcuL3BhdGNoLmpzJyk7XG52YXIgVXRpbCA9IHJlcXVpcmUoJy4vdXRpbC5qcycpO1xuXG5mdW5jdGlvbiBEZW1hbmRNYXRjaGVyKGRlbWFuZFNwZWMsIHN1cHBseVNwZWMsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IFV0aWwuZXh0ZW5kKHtcbiAgICBtZXRhTGV2ZWw6IDAsXG4gICAgb25EZW1hbmRJbmNyZWFzZTogZnVuY3Rpb24gKGNhcHR1cmVzKSB7XG4gICAgICBjb25zb2xlLmVycm9yKFwiU3luZGljYXRlOiBVbmhhbmRsZWQgaW5jcmVhc2UgaW4gZGVtYW5kXCIsIGNhcHR1cmVzKTtcbiAgICB9LFxuICAgIG9uU3VwcGx5RGVjcmVhc2U6IGZ1bmN0aW9uIChjYXB0dXJlcykge1xuICAgICAgY29uc29sZS5lcnJvcihcIlN5bmRpY2F0ZTogVW5oYW5kbGVkIGRlY3JlYXNlIGluIHN1cHBseVwiLCBjYXB0dXJlcyk7XG4gICAgfVxuICB9LCBvcHRpb25zKTtcbiAgdGhpcy5tZXRhTGV2ZWwgPSBvcHRpb25zLm1ldGFMZXZlbDtcbiAgdGhpcy5vbkRlbWFuZEluY3JlYXNlID0gb3B0aW9ucy5vbkRlbWFuZEluY3JlYXNlO1xuICB0aGlzLm9uU3VwcGx5RGVjcmVhc2UgPSBvcHRpb25zLm9uU3VwcGx5RGVjcmVhc2U7XG4gIHRoaXMuZGVtYW5kU3BlYyA9IGRlbWFuZFNwZWM7XG4gIHRoaXMuc3VwcGx5U3BlYyA9IHN1cHBseVNwZWM7XG4gIHRoaXMuZGVtYW5kUGF0dGVybiA9IFJvdXRlLnByb2plY3Rpb25Ub1BhdHRlcm4oZGVtYW5kU3BlYyk7XG4gIHRoaXMuc3VwcGx5UGF0dGVybiA9IFJvdXRlLnByb2plY3Rpb25Ub1BhdHRlcm4oc3VwcGx5U3BlYyk7XG4gIHRoaXMuZGVtYW5kUHJvamVjdGlvbiA9IFJvdXRlLmNvbXBpbGVQcm9qZWN0aW9uKFBhdGNoLnByZXBlbmRBdE1ldGEoZGVtYW5kU3BlYywgdGhpcy5tZXRhTGV2ZWwpKTtcbiAgdGhpcy5zdXBwbHlQcm9qZWN0aW9uID0gUm91dGUuY29tcGlsZVByb2plY3Rpb24oUGF0Y2gucHJlcGVuZEF0TWV0YShzdXBwbHlTcGVjLCB0aGlzLm1ldGFMZXZlbCkpO1xuICB0aGlzLmN1cnJlbnREZW1hbmQgPSBJbW11dGFibGUuU2V0KCk7XG4gIHRoaXMuY3VycmVudFN1cHBseSA9IEltbXV0YWJsZS5TZXQoKTtcbn1cblxuRGVtYW5kTWF0Y2hlci5wcm90b3R5cGUuYm9vdCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIFBhdGNoLnN1Yih0aGlzLmRlbWFuZFBhdHRlcm4sIHRoaXMubWV0YUxldmVsKVxuICAgIC5hbmRUaGVuKFBhdGNoLnN1Yih0aGlzLnN1cHBseVBhdHRlcm4sIHRoaXMubWV0YUxldmVsKSk7XG59O1xuXG5EZW1hbmRNYXRjaGVyLnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChlKSB7XG4gIGlmIChlLnR5cGUgPT09IFwic3RhdGVDaGFuZ2VcIikge1xuICAgIHRoaXMuaGFuZGxlUGF0Y2goZS5wYXRjaCk7XG4gIH1cbn07XG5cbkRlbWFuZE1hdGNoZXIucHJvdG90eXBlLmhhbmRsZVBhdGNoID0gZnVuY3Rpb24gKHApIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHZhciBhZGRlZERlbWFuZCA9IFJvdXRlLnRyaWVLZXlzKFJvdXRlLnByb2plY3QocC5hZGRlZCwgc2VsZi5kZW1hbmRQcm9qZWN0aW9uKSk7XG4gIHZhciByZW1vdmVkRGVtYW5kID0gUm91dGUudHJpZUtleXMoUm91dGUucHJvamVjdChwLnJlbW92ZWQsIHNlbGYuZGVtYW5kUHJvamVjdGlvbikpO1xuICB2YXIgYWRkZWRTdXBwbHkgPSBSb3V0ZS50cmllS2V5cyhSb3V0ZS5wcm9qZWN0KHAuYWRkZWQsIHNlbGYuc3VwcGx5UHJvamVjdGlvbikpO1xuICB2YXIgcmVtb3ZlZFN1cHBseSA9IFJvdXRlLnRyaWVLZXlzKFJvdXRlLnByb2plY3QocC5yZW1vdmVkLCBzZWxmLnN1cHBseVByb2plY3Rpb24pKTtcblxuICBpZiAoYWRkZWREZW1hbmQgPT09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJTeW5kaWNhdGU6IHdpbGRjYXJkIGRlbWFuZCBkZXRlY3RlZDpcXG5cIiArXG5cdFx0ICAgIHNlbGYuZGVtYW5kU3BlYyArIFwiXFxuXCIgK1xuXHRcdCAgICBwLnByZXR0eSgpKTtcbiAgfVxuICBpZiAoYWRkZWRTdXBwbHkgPT09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJTeW5kaWNhdGU6IHdpbGRjYXJkIHN1cHBseSBkZXRlY3RlZDpcXG5cIiArXG5cdFx0ICAgIHNlbGYuc3VwcGx5U3BlYyArIFwiXFxuXCIgK1xuXHRcdCAgICBwLnByZXR0eSgpKTtcbiAgfVxuXG4gIHNlbGYuY3VycmVudFN1cHBseSA9IHNlbGYuY3VycmVudFN1cHBseS51bmlvbihhZGRlZFN1cHBseSk7XG4gIHNlbGYuY3VycmVudERlbWFuZCA9IHNlbGYuY3VycmVudERlbWFuZC5zdWJ0cmFjdChyZW1vdmVkRGVtYW5kKTtcblxuICByZW1vdmVkU3VwcGx5LmZvckVhY2goZnVuY3Rpb24gKGNhcHR1cmVzKSB7XG4gICAgaWYgKHNlbGYuY3VycmVudERlbWFuZC5oYXMoY2FwdHVyZXMpKSB7XG4gICAgICBzZWxmLm9uU3VwcGx5RGVjcmVhc2UoUm91dGUuY2FwdHVyZVRvT2JqZWN0KGNhcHR1cmVzLCBzZWxmLnN1cHBseVByb2plY3Rpb24pKTtcbiAgICB9XG4gIH0pO1xuICBhZGRlZERlbWFuZC5mb3JFYWNoKGZ1bmN0aW9uIChjYXB0dXJlcykge1xuICAgIGlmICghc2VsZi5jdXJyZW50U3VwcGx5LmhhcyhjYXB0dXJlcykpIHtcbiAgICAgIHNlbGYub25EZW1hbmRJbmNyZWFzZShSb3V0ZS5jYXB0dXJlVG9PYmplY3QoY2FwdHVyZXMsIHNlbGYuZGVtYW5kUHJvamVjdGlvbikpO1xuICAgIH1cbiAgfSk7XG5cbiAgc2VsZi5jdXJyZW50U3VwcGx5ID0gc2VsZi5jdXJyZW50U3VwcGx5LnN1YnRyYWN0KHJlbW92ZWRTdXBwbHkpO1xuICBzZWxmLmN1cnJlbnREZW1hbmQgPSBzZWxmLmN1cnJlbnREZW1hbmQudW5pb24oYWRkZWREZW1hbmQpO1xufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbm1vZHVsZS5leHBvcnRzLkRlbWFuZE1hdGNoZXIgPSBEZW1hbmRNYXRjaGVyO1xuIiwiLy8gRE9NIGZyYWdtZW50IGRpc3BsYXkgZHJpdmVyXG52YXIgUGF0Y2ggPSByZXF1aXJlKFwiLi9wYXRjaC5qc1wiKTtcbnZhciBEZW1hbmRNYXRjaGVyID0gcmVxdWlyZSgnLi9kZW1hbmQtbWF0Y2hlci5qcycpLkRlbWFuZE1hdGNoZXI7XG52YXIgQWNrID0gcmVxdWlyZSgnLi9hY2suanMnKS5BY2s7XG52YXIgU2VhbCA9IHJlcXVpcmUoJy4vc2VhbC5qcycpLlNlYWw7XG5cbnZhciBEYXRhc3BhY2VfID0gcmVxdWlyZShcIi4vZGF0YXNwYWNlLmpzXCIpO1xudmFyIERhdGFzcGFjZSA9IERhdGFzcGFjZV8uRGF0YXNwYWNlO1xudmFyIF9fID0gRGF0YXNwYWNlXy5fXztcbnZhciBfJCA9IERhdGFzcGFjZV8uXyQ7XG5cbmZ1bmN0aW9uIHNwYXduRE9NRHJpdmVyKGRvbVdyYXBGdW5jdGlvbiwgalF1ZXJ5V3JhcEZ1bmN0aW9uKSB7XG4gIGRvbVdyYXBGdW5jdGlvbiA9IGRvbVdyYXBGdW5jdGlvbiB8fCBkZWZhdWx0V3JhcEZ1bmN0aW9uO1xuICB2YXIgc3BlYyA9IGRvbVdyYXBGdW5jdGlvbihfJCgnc2VsZWN0b3InKSwgXyQoJ2ZyYWdtZW50Q2xhc3MnKSwgXyQoJ2ZyYWdtZW50U3BlYycpKTtcbiAgRGF0YXNwYWNlLnNwYXduKFxuICAgIG5ldyBEZW1hbmRNYXRjaGVyKHNwZWMsXG5cdFx0ICAgICAgUGF0Y2guYWR2ZXJ0aXNlKHNwZWMpLFxuXHRcdCAgICAgIHtcblx0XHRcdG9uRGVtYW5kSW5jcmVhc2U6IGZ1bmN0aW9uIChjKSB7XG5cdFx0XHQgIERhdGFzcGFjZS5zcGF3bihuZXcgRE9NRnJhZ21lbnQoYy5zZWxlY3Rvcixcblx0XHRcdFx0XHRcdFx0Yy5mcmFnbWVudENsYXNzLFxuXHRcdFx0XHRcdFx0XHRjLmZyYWdtZW50U3BlYyxcblx0XHRcdFx0XHRcdFx0ZG9tV3JhcEZ1bmN0aW9uLFxuXHRcdFx0XHRcdFx0XHRqUXVlcnlXcmFwRnVuY3Rpb24pKTtcblx0XHRcdH1cblx0XHQgICAgICB9KSk7XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRXcmFwRnVuY3Rpb24oc2VsZWN0b3IsIGZyYWdtZW50Q2xhc3MsIGZyYWdtZW50U3BlYykge1xuICByZXR1cm4gW1wiRE9NXCIsIHNlbGVjdG9yLCBmcmFnbWVudENsYXNzLCBmcmFnbWVudFNwZWNdO1xufVxuXG5mdW5jdGlvbiBET01GcmFnbWVudChzZWxlY3RvciwgZnJhZ21lbnRDbGFzcywgZnJhZ21lbnRTcGVjLCBkb21XcmFwRnVuY3Rpb24sIGpRdWVyeVdyYXBGdW5jdGlvbikge1xuICB0aGlzLnNlbGVjdG9yID0gc2VsZWN0b3I7XG4gIHRoaXMuZnJhZ21lbnRDbGFzcyA9IGZyYWdtZW50Q2xhc3M7XG4gIHRoaXMuZnJhZ21lbnRTcGVjID0gZnJhZ21lbnRTcGVjO1xuICB0aGlzLmRvbVdyYXBGdW5jdGlvbiA9IGRvbVdyYXBGdW5jdGlvbjtcbiAgdGhpcy5qUXVlcnlXcmFwRnVuY3Rpb24gPSBqUXVlcnlXcmFwRnVuY3Rpb247XG4gIHRoaXMuZGVtYW5kRXhpc3RzID0gZmFsc2U7XG4gIHRoaXMuc3Vic2NyaXB0aW9uRXN0YWJsaXNoZWQgPSBuZXcgQWNrKCk7XG4gIHRoaXMubm9kZXMgPSB0aGlzLmJ1aWxkTm9kZXMoKTtcbn1cblxuRE9NRnJhZ21lbnQucHJvdG90eXBlLmJvb3QgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHNwZWNpZmljYXRpb24gPSBzZWxmLmRvbVdyYXBGdW5jdGlvbihzZWxmLnNlbGVjdG9yLCBzZWxmLmZyYWdtZW50Q2xhc3MsIHNlbGYuZnJhZ21lbnRTcGVjKTtcblxuICBEYXRhc3BhY2Uuc3Bhd24obmV3IERhdGFzcGFjZShmdW5jdGlvbiAoKSB7XG4gICAgU3luZGljYXRlLkpRdWVyeS5zcGF3bkpRdWVyeURyaXZlcihzZWxmLnNlbGVjdG9yK1wiID4gLlwiK3NlbGYuZnJhZ21lbnRDbGFzcyxcblx0XHRcdFx0ICAgICAgIDEsXG5cdFx0XHRcdCAgICAgICBzZWxmLmpRdWVyeVdyYXBGdW5jdGlvbik7XG4gICAgRGF0YXNwYWNlLnNwYXduKHtcbiAgICAgIGRlbWFuZEV4aXN0czogZmFsc2UsXG4gICAgICBzdWJzY3JpcHRpb25Fc3RhYmxpc2hlZDogbmV3IEFjaygxKSxcbiAgICAgIGJvb3Q6IGZ1bmN0aW9uICgpIHtcblx0dGhpcy5zdWJzY3JpcHRpb25Fc3RhYmxpc2hlZC5hcm0oKTtcblx0cmV0dXJuIFBhdGNoLnN1YihQYXRjaC5hZHZlcnRpc2Uoc3BlY2lmaWNhdGlvbiksIDEpO1xuICAgICAgfSxcbiAgICAgIGhhbmRsZUV2ZW50OiBmdW5jdGlvbiAoZSkge1xuXHR0aGlzLnN1YnNjcmlwdGlvbkVzdGFibGlzaGVkLmNoZWNrKGUpO1xuXHRpZiAoZS50eXBlID09PSBcInN0YXRlQ2hhbmdlXCIpIHtcblx0ICBpZiAoZS5wYXRjaC5oYXNBZGRlZCgpKSB0aGlzLmRlbWFuZEV4aXN0cyA9IHRydWU7XG5cdCAgaWYgKGUucGF0Y2guaGFzUmVtb3ZlZCgpKSB0aGlzLmRlbWFuZEV4aXN0cyA9IGZhbHNlO1xuXHR9XG5cdGlmICh0aGlzLnN1YnNjcmlwdGlvbkVzdGFibGlzaGVkLmRvbmUgJiYgIXRoaXMuZGVtYW5kRXhpc3RzKSB7XG5cdCAgRGF0YXNwYWNlLmV4aXREYXRhc3BhY2UoKTtcblx0fVxuICAgICAgfVxuICAgIH0pO1xuICB9KSk7XG5cbiAgdGhpcy5zdWJzY3JpcHRpb25Fc3RhYmxpc2hlZC5hcm0oKTtcbiAgcmV0dXJuIFBhdGNoLnN1YihzcGVjaWZpY2F0aW9uKS5hbmRUaGVuKFBhdGNoLnB1YihzcGVjaWZpY2F0aW9uKSk7XG59O1xuXG5ET01GcmFnbWVudC5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAoZSkge1xuICB0aGlzLnN1YnNjcmlwdGlvbkVzdGFibGlzaGVkLmNoZWNrKGUpO1xuICBpZiAoZS50eXBlID09PSBcInN0YXRlQ2hhbmdlXCIpIHtcbiAgICBpZiAoZS5wYXRjaC5oYXNBZGRlZCgpKSB0aGlzLmRlbWFuZEV4aXN0cyA9IHRydWU7XG4gICAgaWYgKGUucGF0Y2guaGFzUmVtb3ZlZCgpKSB0aGlzLmRlbWFuZEV4aXN0cyA9IGZhbHNlO1xuICB9XG4gIGlmICh0aGlzLnN1YnNjcmlwdGlvbkVzdGFibGlzaGVkLmRvbmUgJiYgIXRoaXMuZGVtYW5kRXhpc3RzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLm5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgbiA9IHRoaXMubm9kZXNbaV07XG4gICAgICBuLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobik7XG4gICAgfVxuICAgIERhdGFzcGFjZS5leGl0KCk7XG4gIH1cbn07XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBpc0F0dHJpYnV0ZXMoeCkge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheSh4KSAmJiAoKHgubGVuZ3RoID09PSAwKSB8fCBBcnJheS5pc0FycmF5KHhbMF0pKTtcbn1cblxuRE9NRnJhZ21lbnQucHJvdG90eXBlLmludGVycHJldFNwZWMgPSBmdW5jdGlvbiAoc3BlYykge1xuICAvLyBGcmFnbWVudCBzcGVjcyBhcmUgcm91Z2hseSBKU09OLWVxdWl2YWxlbnRzIG9mIFNYTUwuXG4gIC8vIHNwZWMgOjo9PSBbXCJ0YWdcIiwgW1tcImF0dHJcIiwgXCJ2YWx1ZVwiXSwgLi4uXSwgc3BlYywgc3BlYywgLi4uXVxuICAvLyAgICAgICAgIHwgW1widGFnXCIsIHNwZWMsIHNwZWMsIC4uLl1cbiAgLy8gICAgICAgICB8IFwiY2RhdGFcIlxuICBpZiAodHlwZW9mKHNwZWMpID09PSBcInN0cmluZ1wiIHx8IHR5cGVvZihzcGVjKSA9PT0gXCJudW1iZXJcIikge1xuICAgIHJldHVybiBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShzcGVjKTtcbiAgfSBlbHNlIGlmICgkLmlzQXJyYXkoc3BlYykpIHtcbiAgICB2YXIgdGFnTmFtZSA9IHNwZWNbMF07XG4gICAgdmFyIGhhc0F0dHJzID0gaXNBdHRyaWJ1dGVzKHNwZWNbMV0pO1xuICAgIHZhciBhdHRycyA9IGhhc0F0dHJzID8gc3BlY1sxXSA6IHt9O1xuICAgIHZhciBraWRJbmRleCA9IGhhc0F0dHJzID8gMiA6IDE7XG5cbiAgICAvLyBXb3chIFN1Y2ggWFNTISBNYW55IGhhY2tzISBTbyB2dWxuZXJhYmlsaXR5ISBBbWF6ZSFcbiAgICB2YXIgbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhdHRycy5sZW5ndGg7IGkrKykge1xuICAgICAgbi5zZXRBdHRyaWJ1dGUoYXR0cnNbaV1bMF0sIGF0dHJzW2ldWzFdKTtcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IGtpZEluZGV4OyBpIDwgc3BlYy5sZW5ndGg7IGkrKykge1xuICAgICAgbi5hcHBlbmRDaGlsZCh0aGlzLmludGVycHJldFNwZWMoc3BlY1tpXSkpO1xuICAgIH1cbiAgICByZXR1cm4gbjtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbGwtZm9ybWVkIERPTSBzcGVjaWZpY2F0aW9uXCIpO1xuICB9XG59O1xuXG5ET01GcmFnbWVudC5wcm90b3R5cGUuYnVpbGROb2RlcyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgbm9kZXMgPSBbXTtcbiAgJChzZWxmLnNlbGVjdG9yKS5lYWNoKGZ1bmN0aW9uIChpbmRleCwgZG9tTm9kZSkge1xuICAgIHZhciBuID0gc2VsZi5pbnRlcnByZXRTcGVjKHNlbGYuZnJhZ21lbnRTcGVjLnNlYWxDb250ZW50cyk7XG4gICAgaWYgKCdjbGFzc0xpc3QnIGluIG4pIHtcbiAgICAgIG4uY2xhc3NMaXN0LmFkZChzZWxmLmZyYWdtZW50Q2xhc3MpO1xuICAgIH1cbiAgICBkb21Ob2RlLmFwcGVuZENoaWxkKG4pO1xuICAgIG5vZGVzLnB1c2gobik7XG4gIH0pO1xuICByZXR1cm4gbm9kZXM7XG59O1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxubW9kdWxlLmV4cG9ydHMuc3Bhd25ET01Ecml2ZXIgPSBzcGF3bkRPTURyaXZlcjtcbm1vZHVsZS5leHBvcnRzLmRlZmF1bHRXcmFwRnVuY3Rpb24gPSBkZWZhdWx0V3JhcEZ1bmN0aW9uO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBJbW11dGFibGUgPSByZXF1aXJlKCdpbW11dGFibGUnKTtcbnZhciBEYXRhc3BhY2UgPSByZXF1aXJlKCcuL2RhdGFzcGFjZS5qcycpLkRhdGFzcGFjZTtcblxuZnVuY3Rpb24gR3JvdW5kKGJvb3RGbikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuc3RlcHBlcklkID0gbnVsbDtcbiAgdGhpcy5iYXNlU3RhY2sgPSBJbW11dGFibGUuTGlzdC5vZih7IGRhdGFzcGFjZTogdGhpcywgYWN0aXZlUGlkOiAtMSB9KTtcbiAgRGF0YXNwYWNlLndpdGhEYXRhc3BhY2VTdGFjayh0aGlzLmJhc2VTdGFjaywgZnVuY3Rpb24gKCkge1xuICAgIHNlbGYuZGF0YXNwYWNlID0gbmV3IERhdGFzcGFjZShib290Rm4pO1xuICB9KTtcbn1cblxuR3JvdW5kLnByb3RvdHlwZS5zdGVwID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHJldHVybiBEYXRhc3BhY2Uud2l0aERhdGFzcGFjZVN0YWNrKHRoaXMuYmFzZVN0YWNrLCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHNlbGYuZGF0YXNwYWNlLnN0ZXAoKTtcbiAgfSk7XG59O1xuXG5Hcm91bmQucHJvdG90eXBlLmNoZWNrUGlkID0gZnVuY3Rpb24gKHBpZCkge1xuICBpZiAocGlkICE9PSAtMSkgY29uc29sZS5lcnJvcignV2VpcmQgcGlkIGluIEdyb3VuZCcsIHBpZCk7XG59O1xuXG5Hcm91bmQucHJvdG90eXBlLm1hcmtSdW5uYWJsZSA9IGZ1bmN0aW9uIChwaWQpIHtcbiAgdGhpcy5jaGVja1BpZChwaWQpO1xuICB0aGlzLnN0YXJ0U3RlcHBpbmcoKTtcbn07XG5cbkdyb3VuZC5wcm90b3R5cGUuc3RhcnRTdGVwcGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBpZiAodGhpcy5zdGVwcGVySWQpIHJldHVybjtcbiAgaWYgKHRoaXMuc3RlcCgpKSB7XG4gICAgdGhpcy5zdGVwcGVySWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHNlbGYuc3RlcHBlcklkID0gbnVsbDtcbiAgICAgIHNlbGYuc3RhcnRTdGVwcGluZygpO1xuICAgIH0sIDApO1xuICB9XG4gIHJldHVybiB0aGlzOyAvLyBiZWNhdXNlIHRoZSBzeW5kaWNhdGVjIGNvbXBpbGVyIGNoYWlucyBzdGFydFN0ZXBwaW5nIGFmdGVyIHRoZSBjdG9yXG59O1xuXG5Hcm91bmQucHJvdG90eXBlLnN0b3BTdGVwcGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuc3RlcHBlcklkKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuc3RlcHBlcklkKTtcbiAgICB0aGlzLnN0ZXBwZXJJZCA9IG51bGw7XG4gIH1cbn07XG5cbkdyb3VuZC5wcm90b3R5cGUua2lsbCA9IGZ1bmN0aW9uIChwaWQsIGV4bikge1xuICB0aGlzLmNoZWNrUGlkKHBpZCk7XG4gIGNvbnNvbGUubG9nKFwiR3JvdW5kIGRhdGFzcGFjZSB0ZXJtaW5hdGVkXCIpO1xuICB0aGlzLnN0b3BTdGVwcGluZygpO1xufTtcblxuR3JvdW5kLnByb3RvdHlwZS5lbnF1ZXVlQWN0aW9uID0gZnVuY3Rpb24gKHBpZCwgYWN0aW9uKSB7XG4gIHRoaXMuY2hlY2tQaWQocGlkKTtcblxuICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gIGNhc2UgJ3N0YXRlQ2hhbmdlJzpcbiAgICBpZiAoYWN0aW9uLnBhdGNoLmlzTm9uRW1wdHkoKSkge1xuICAgICAgY29uc29sZS5lcnJvcignWW91IGhhdmUgc3Vic2NyaWJlZCB0byBhIG5vbmV4aXN0ZW50IGV2ZW50IHNvdXJjZS4nLFxuXHRcdCAgICBhY3Rpb24ucGF0Y2gucHJldHR5KCkpO1xuICAgIH1cbiAgICBicmVhaztcblxuICBjYXNlICdtZXNzYWdlJzpcbiAgICBjb25zb2xlLmVycm9yKCdZb3UgaGF2ZSBzZW50IGEgbWVzc2FnZSBpbnRvIHRoZSBvdXRlciB2b2lkLicsIGFjdGlvbik7XG4gICAgYnJlYWs7XG5cbiAgZGVmYXVsdDpcbiAgICBjb25zb2xlLmVycm9yKCdJbnRlcm5hbCBlcnJvcjogdW5leHBlY3RlZCBhY3Rpb24gYXQgZ3JvdW5kIGxldmVsJywgYWN0aW9uKTtcbiAgICBicmVhaztcbiAgfVxufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbm1vZHVsZS5leHBvcnRzLkdyb3VuZCA9IEdyb3VuZDtcbiIsIi8vIEpRdWVyeSBldmVudCBkcml2ZXJcbnZhciBQYXRjaCA9IHJlcXVpcmUoXCIuL3BhdGNoLmpzXCIpO1xudmFyIERlbWFuZE1hdGNoZXIgPSByZXF1aXJlKCcuL2RlbWFuZC1tYXRjaGVyLmpzJykuRGVtYW5kTWF0Y2hlcjtcblxudmFyIERhdGFzcGFjZV8gPSByZXF1aXJlKFwiLi9kYXRhc3BhY2UuanNcIik7XG52YXIgRGF0YXNwYWNlID0gRGF0YXNwYWNlXy5EYXRhc3BhY2U7XG52YXIgX18gPSBEYXRhc3BhY2VfLl9fO1xudmFyIF8kID0gRGF0YXNwYWNlXy5fJDtcblxuZnVuY3Rpb24gc3Bhd25KUXVlcnlEcml2ZXIoYmFzZVNlbGVjdG9yLCBtZXRhTGV2ZWwsIHdyYXBGdW5jdGlvbikge1xuICBtZXRhTGV2ZWwgPSBtZXRhTGV2ZWwgfHwgMDtcbiAgd3JhcEZ1bmN0aW9uID0gd3JhcEZ1bmN0aW9uIHx8IGRlZmF1bHRXcmFwRnVuY3Rpb247XG4gIERhdGFzcGFjZS5zcGF3bihcbiAgICBuZXcgRGVtYW5kTWF0Y2hlcihQYXRjaC5vYnNlcnZlKHdyYXBGdW5jdGlvbihfJCgnc2VsZWN0b3InKSwgXyQoJ2V2ZW50TmFtZScpLCBfXykpLFxuXHRcdCAgICAgIFBhdGNoLmFkdmVydGlzZSh3cmFwRnVuY3Rpb24oXyQoJ3NlbGVjdG9yJyksIF8kKCdldmVudE5hbWUnKSwgX18pKSxcblx0XHQgICAgICB7XG5cdFx0XHRtZXRhTGV2ZWw6IG1ldGFMZXZlbCxcblx0XHRcdG9uRGVtYW5kSW5jcmVhc2U6IGZ1bmN0aW9uIChjKSB7XG5cdFx0XHQgIERhdGFzcGFjZS5zcGF3bihuZXcgSlF1ZXJ5RXZlbnRSb3V0ZXIoYmFzZVNlbGVjdG9yLFxuXHRcdFx0XHRcdFx0XHQgICAgICBjLnNlbGVjdG9yLFxuXHRcdFx0XHRcdFx0XHQgICAgICBjLmV2ZW50TmFtZSxcblx0XHRcdFx0XHRcdFx0ICAgICAgbWV0YUxldmVsLFxuXHRcdFx0XHRcdFx0XHQgICAgICB3cmFwRnVuY3Rpb24pKTtcblx0XHRcdH1cblx0XHQgICAgICB9KSk7XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRXcmFwRnVuY3Rpb24oc2VsZWN0b3IsIGV2ZW50TmFtZSwgZXZlbnRWYWx1ZSkge1xuICByZXR1cm4gW1wialF1ZXJ5XCIsIHNlbGVjdG9yLCBldmVudE5hbWUsIGV2ZW50VmFsdWVdO1xufVxuXG5mdW5jdGlvbiBKUXVlcnlFdmVudFJvdXRlcihiYXNlU2VsZWN0b3IsIHNlbGVjdG9yLCBldmVudE5hbWUsIG1ldGFMZXZlbCwgd3JhcEZ1bmN0aW9uKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5iYXNlU2VsZWN0b3IgPSBiYXNlU2VsZWN0b3IgfHwgbnVsbDtcbiAgdGhpcy5zZWxlY3RvciA9IHNlbGVjdG9yO1xuICB0aGlzLmV2ZW50TmFtZSA9IGV2ZW50TmFtZTtcbiAgdGhpcy5tZXRhTGV2ZWwgPSBtZXRhTGV2ZWwgfHwgMDtcbiAgdGhpcy53cmFwRnVuY3Rpb24gPSB3cmFwRnVuY3Rpb24gfHwgZGVmYXVsdFdyYXBGdW5jdGlvbjtcbiAgdGhpcy5wcmV2ZW50RGVmYXVsdCA9ICh0aGlzLmV2ZW50TmFtZS5jaGFyQXQoMCkgIT09IFwiK1wiKTtcbiAgdGhpcy5oYW5kbGVyID1cbiAgICBEYXRhc3BhY2Uud3JhcChmdW5jdGlvbiAoZSkge1xuICAgICAgRGF0YXNwYWNlLnNlbmQoc2VsZi53cmFwRnVuY3Rpb24oc2VsZi5zZWxlY3Rvciwgc2VsZi5ldmVudE5hbWUsIGUpLCBzZWxmLm1ldGFMZXZlbCk7XG4gICAgICBpZiAoc2VsZi5wcmV2ZW50RGVmYXVsdCkgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgcmV0dXJuICFzZWxmLnByZXZlbnREZWZhdWx0O1xuICAgIH0pO1xuICB0aGlzLmNvbXB1dGVOb2RlcygpLm9uKHRoaXMucHJldmVudERlZmF1bHQgPyB0aGlzLmV2ZW50TmFtZSA6IHRoaXMuZXZlbnROYW1lLnN1YnN0cmluZygxKSxcblx0XHRcdCB0aGlzLmhhbmRsZXIpO1xufVxuXG5KUXVlcnlFdmVudFJvdXRlci5wcm90b3R5cGUuYm9vdCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIFBhdGNoLnB1Yih0aGlzLndyYXBGdW5jdGlvbih0aGlzLnNlbGVjdG9yLCB0aGlzLmV2ZW50TmFtZSwgX18pLCB0aGlzLm1ldGFMZXZlbClcbiAgICAuYW5kVGhlbihQYXRjaC5zdWIoUGF0Y2gub2JzZXJ2ZSh0aGlzLndyYXBGdW5jdGlvbih0aGlzLnNlbGVjdG9yLCB0aGlzLmV2ZW50TmFtZSwgX18pKSxcblx0XHQgICAgICAgdGhpcy5tZXRhTGV2ZWwpKTtcbn07XG5cbkpRdWVyeUV2ZW50Um91dGVyLnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChlKSB7XG4gIGlmIChlLnR5cGUgPT09IFwic3RhdGVDaGFuZ2VcIiAmJiBlLnBhdGNoLmhhc1JlbW92ZWQoKSkge1xuICAgIHRoaXMuY29tcHV0ZU5vZGVzKCkub2ZmKHRoaXMuZXZlbnROYW1lLCB0aGlzLmhhbmRsZXIpO1xuICAgIERhdGFzcGFjZS5leGl0KCk7XG4gIH1cbn07XG5cbkpRdWVyeUV2ZW50Um91dGVyLnByb3RvdHlwZS5jb21wdXRlTm9kZXMgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmJhc2VTZWxlY3Rvcikge1xuICAgIHJldHVybiAkKHRoaXMuYmFzZVNlbGVjdG9yKS5jaGlsZHJlbih0aGlzLnNlbGVjdG9yKS5hZGRCYWNrKHRoaXMuc2VsZWN0b3IpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAkKHRoaXMuc2VsZWN0b3IpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBzaW1wbGlmeURPTUV2ZW50KGUpIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIgayBpbiBlKSB7XG4gICAgdmFyIHYgPSBlW2tdO1xuICAgIGlmICh0eXBlb2YgdiA9PT0gJ29iamVjdCcpIGNvbnRpbnVlO1xuICAgIGlmICh0eXBlb2YgdiA9PT0gJ2Z1bmN0aW9uJykgY29udGludWU7XG4gICAga2V5cy5wdXNoKGspO1xuICB9XG4gIGtleXMuc29ydCgpO1xuICB2YXIgc2ltcGxpZmllZCA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICBzaW1wbGlmaWVkLnB1c2goW2tleXNbaV0sIGVba2V5c1tpXV1dKTtcbiAgfVxuICByZXR1cm4gc2ltcGxpZmllZDtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbm1vZHVsZS5leHBvcnRzLnNwYXduSlF1ZXJ5RHJpdmVyID0gc3Bhd25KUXVlcnlEcml2ZXI7XG5tb2R1bGUuZXhwb3J0cy5zaW1wbGlmeURPTUV2ZW50ID0gc2ltcGxpZnlET01FdmVudDtcbm1vZHVsZS5leHBvcnRzLmRlZmF1bHRXcmFwRnVuY3Rpb24gPSBkZWZhdWx0V3JhcEZ1bmN0aW9uO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbmZ1bmN0aW9uIGNvcHlLZXlzKGtleXMsIHRvLCBmcm9tKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIHRvW2tleXNbaV1dID0gZnJvbVtrZXlzW2ldXTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuL2RhdGFzcGFjZS5qc1wiKTtcblxubW9kdWxlLmV4cG9ydHMuUm91dGUgPSByZXF1aXJlKFwiLi9yb3V0ZS5qc1wiKTtcbmNvcHlLZXlzKFsnX18nLCAnXyQnLCAnJENhcHR1cmUnLCAnJFNwZWNpYWwnLFxuXHQgICdpc19lbXB0eVRyaWUnLCAnZW1wdHlUcmllJyxcblx0ICAnZW1iZWRkZWRUcmllJywgJ2NvbXBpbGVQYXR0ZXJuJyxcblx0ICAnY29tcGlsZVByb2plY3Rpb24nLCAncHJvamVjdCcsICdwcm9qZWN0T2JqZWN0cycsXG5cdCAgJ3ByZXR0eVRyaWUnXSxcblx0IG1vZHVsZS5leHBvcnRzLFxuXHQgbW9kdWxlLmV4cG9ydHMuUm91dGUpO1xuXG52YXIgU2VhbCA9IHJlcXVpcmUoJy4vc2VhbC5qcycpXG5jb3B5S2V5cyhbJ1NlYWwnLCAnc2VhbCddLFxuXHQgbW9kdWxlLmV4cG9ydHMsXG5cdCBTZWFsKTtcblxubW9kdWxlLmV4cG9ydHMuRGVtYW5kTWF0Y2hlciA9IHJlcXVpcmUoJy4vZGVtYW5kLW1hdGNoZXIuanMnKS5EZW1hbmRNYXRjaGVyO1xubW9kdWxlLmV4cG9ydHMuQWNrID0gcmVxdWlyZSgnLi9hY2suanMnKS5BY2s7XG5cbm1vZHVsZS5leHBvcnRzLlJhbmRvbUlEID0gcmVxdWlyZSgnLi9yYW5kb21pZC5qcycpO1xubW9kdWxlLmV4cG9ydHMuRE9NID0gcmVxdWlyZShcIi4vZG9tLWRyaXZlci5qc1wiKTtcbm1vZHVsZS5leHBvcnRzLkpRdWVyeSA9IHJlcXVpcmUoXCIuL2pxdWVyeS1kcml2ZXIuanNcIik7XG4vLyBtb2R1bGUuZXhwb3J0cy5Sb3V0aW5nVGFibGVXaWRnZXQgPSByZXF1aXJlKFwiLi9yb3V0aW5nLXRhYmxlLXdpZGdldC5qc1wiKTtcbi8vIG1vZHVsZS5leHBvcnRzLldlYlNvY2tldCA9IHJlcXVpcmUoXCIuL3dlYnNvY2tldC1kcml2ZXIuanNcIik7XG5tb2R1bGUuZXhwb3J0cy5SZWZsZWN0ID0gcmVxdWlyZShcIi4vcmVmbGVjdC5qc1wiKTtcblxubW9kdWxlLmV4cG9ydHMuUGF0Y2ggPSByZXF1aXJlKFwiLi9wYXRjaC5qc1wiKTtcbmNvcHlLZXlzKFsnZW1wdHlQYXRjaCcsXG5cdCAgJ29ic2VydmUnLCAnYXRNZXRhJywgJ2FkdmVydGlzZScsXG5cdCAgJ2lzT2JzZXJ2ZScsICdpc0F0TWV0YScsICdpc0FkdmVydGlzZScsXG5cdCAgJ2Fzc2VydCcsICdyZXRyYWN0JywgJ3N1YicsICd1bnN1YicsICdwdWInLCAndW5wdWInLFxuXHQgICdwYXRjaFNlcSddLFxuXHQgbW9kdWxlLmV4cG9ydHMsXG5cdCBtb2R1bGUuZXhwb3J0cy5QYXRjaCk7XG5cbm1vZHVsZS5leHBvcnRzLkdyb3VuZCA9IHJlcXVpcmUoXCIuL2dyb3VuZC5qc1wiKS5Hcm91bmQ7XG5tb2R1bGUuZXhwb3J0cy5BY3RvciA9IHJlcXVpcmUoXCIuL2FjdG9yLmpzXCIpO1xuLy8gbW9kdWxlLmV4cG9ydHMuU3B5ID0gcmVxdWlyZShcIi4vc3B5LmpzXCIpLlNweTtcbi8vIG1vZHVsZS5leHBvcnRzLldha2VEZXRlY3RvciA9IHJlcXVpcmUoXCIuL3dha2UtZGV0ZWN0b3IuanNcIikuV2FrZURldGVjdG9yO1xuXG4vLyB2YXIgV29ya2VyID0gcmVxdWlyZShcIi4vd29ya2VyLmpzXCIpO1xuLy8gbW9kdWxlLmV4cG9ydHMuV29ya2VyID0gV29ya2VyLldvcmtlcjtcbi8vIG1vZHVsZS5leHBvcnRzLldvcmtlckdyb3VuZCA9IFdvcmtlci5Xb3JrZXJHcm91bmQ7XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIEltbXV0YWJsZSA9IHJlcXVpcmUoJ2ltbXV0YWJsZScpO1xudmFyIFJvdXRlID0gcmVxdWlyZSgnLi9yb3V0ZS5qcycpO1xudmFyIFBhdGNoID0gcmVxdWlyZSgnLi9wYXRjaC5qcycpO1xuXG5mdW5jdGlvbiBNdXgobmV4dFBpZCwgcm91dGluZ1RhYmxlLCBpbnRlcmVzdFRhYmxlKSB7XG4gIHRoaXMubmV4dFBpZCA9IG5leHRQaWQgfHwgMDtcbiAgdGhpcy5yb3V0aW5nVGFibGUgPSByb3V0aW5nVGFibGUgfHwgUm91dGUuZW1wdHlUcmllO1xuICB0aGlzLmludGVyZXN0VGFibGUgPSBpbnRlcmVzdFRhYmxlIHx8IEltbXV0YWJsZS5NYXAoKTsgLy8gcGlkIC0+IFRyaWVcbn1cblxuTXV4LnByb3RvdHlwZS5zaGFsbG93Q29weSA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIG5ldyBNdXgodGhpcy5uZXh0UGlkLCB0aGlzLnJvdXRpbmdUYWJsZSwgdGhpcy5pbnRlcmVzdFRhYmxlKTtcbn07XG5cbk11eC5wcm90b3R5cGUuYWRkU3RyZWFtID0gZnVuY3Rpb24gKGluaXRpYWxQYXRjaCkge1xuICB2YXIgbmV3UGlkID0gdGhpcy5uZXh0UGlkKys7XG4gIHJldHVybiB0aGlzLnVwZGF0ZVN0cmVhbShuZXdQaWQsIGluaXRpYWxQYXRjaCk7XG59O1xuXG5NdXgucHJvdG90eXBlLnJlbW92ZVN0cmVhbSA9IGZ1bmN0aW9uIChwaWQpIHtcbiAgcmV0dXJuIHRoaXMudXBkYXRlU3RyZWFtKHBpZCwgUGF0Y2gucmVtb3ZlRXZlcnl0aGluZ1BhdGNoKTtcbn07XG5cbk11eC5wcm90b3R5cGUudXBkYXRlU3RyZWFtID0gZnVuY3Rpb24gKHBpZCwgdW5jbGFtcGVkUGF0Y2gpIHtcbiAgdmFyIG9sZEludGVyZXN0cyA9IHRoaXMuaW50ZXJlc3RzT2YocGlkKTtcbiAgdmFyIG9sZFJvdXRpbmdUYWJsZSA9IHRoaXMucm91dGluZ1RhYmxlO1xuICB2YXIgZGVsdGEgPSB1bmNsYW1wZWRQYXRjaC5sYWJlbChJbW11dGFibGUuU2V0Lm9mKHBpZCkpLmxpbWl0KG9sZEludGVyZXN0cyk7XG4gIHZhciBkZWx0YUFnZ3JlZ2F0ZSA9IGRlbHRhLmNvbXB1dGVBZ2dyZWdhdGUocGlkLCBvbGRSb3V0aW5nVGFibGUpO1xuICB2YXIgbmV3SW50ZXJlc3RzID0gZGVsdGEuYXBwbHlUbyhvbGRJbnRlcmVzdHMpO1xuICB2YXIgbmV3Um91dGluZ1RhYmxlID0gZGVsdGEuYXBwbHlUbyhvbGRSb3V0aW5nVGFibGUpO1xuXG4gIHRoaXMucm91dGluZ1RhYmxlID0gbmV3Um91dGluZ1RhYmxlO1xuXG4gIGlmIChSb3V0ZS5pc19lbXB0eVRyaWUobmV3SW50ZXJlc3RzKSkge1xuICAgIHRoaXMuaW50ZXJlc3RUYWJsZSA9IHRoaXMuaW50ZXJlc3RUYWJsZS5yZW1vdmUocGlkKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmludGVyZXN0VGFibGUgPSB0aGlzLmludGVyZXN0VGFibGUuc2V0KHBpZCwgbmV3SW50ZXJlc3RzKTtcbiAgfVxuXG4gIHJldHVybiB7IHBpZDogcGlkLFxuXHQgICBkZWx0YTogZGVsdGEsXG5cdCAgIGRlbHRhQWdncmVnYXRlOiBkZWx0YUFnZ3JlZ2F0ZSB9O1xufTtcblxudmFyIGF0TWV0YUV2ZXJ5dGhpbmcgPSBSb3V0ZS5jb21waWxlUGF0dGVybih0cnVlLCBQYXRjaC5hdE1ldGEoUm91dGUuX18pKTtcbnZhciBhdE1ldGFCcmFuY2hLZXlzID0gSW1tdXRhYmxlLkxpc3QoW1JvdXRlLlNPQSwgUGF0Y2guJEF0TWV0YV0pO1xudmFyIG9ubHlNZXRhID0gSW1tdXRhYmxlLlNldC5vZihcIm1ldGFcIik7XG5cbmZ1bmN0aW9uIGVjaG9DYW5jZWxsZWRUcmllKHQpIHtcbiAgcmV0dXJuIFJvdXRlLnN1YnRyYWN0KHQsIGF0TWV0YUV2ZXJ5dGhpbmcsIGZ1bmN0aW9uICh2MSwgdjIpIHtcbiAgICByZXR1cm4gdjEuaGFzKFwibWV0YVwiKSA/IG9ubHlNZXRhIDogbnVsbDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVFdmVudHMob2xkTXV4LCBuZXdNdXgsIHVwZGF0ZVN0cmVhbVJlc3VsdCkge1xuICB2YXIgYWN0aW5nUGlkID0gdXBkYXRlU3RyZWFtUmVzdWx0LnBpZDtcbiAgdmFyIGRlbHRhID0gdXBkYXRlU3RyZWFtUmVzdWx0LmRlbHRhO1xuICB2YXIgZGVsdGFBZ2dyZWdhdGUgPSB1cGRhdGVTdHJlYW1SZXN1bHQuZGVsdGFBZ2dyZWdhdGU7XG4gIHZhciBkZWx0YUFnZ3JlZ2F0ZU5vRWNobyA9IChhY3RpbmdQaWQgPT09IFwibWV0YVwiKVxuICAgICAgPyBkZWx0YSAvLyBiZWNhdXNlIGVjaG8tY2FuY2VsbGF0aW9uIG1lYW5zIHRoYXQgbWV0YS1TQ05zIGFyZSBhbHdheXMgbmV3IGluZm9ybWF0aW9uXG4gICAgICA6IG5ldyBQYXRjaC5QYXRjaChSb3V0ZS50cmllUHJ1bmVCcmFuY2goZGVsdGFBZ2dyZWdhdGUuYWRkZWQsIGF0TWV0YUJyYW5jaEtleXMpLFxuXHRcdFx0Um91dGUudHJpZVBydW5lQnJhbmNoKGRlbHRhQWdncmVnYXRlLnJlbW92ZWQsIGF0TWV0YUJyYW5jaEtleXMpKTtcbiAgdmFyIG9sZFJvdXRpbmdUYWJsZSA9IG9sZE11eC5yb3V0aW5nVGFibGU7XG4gIHZhciBuZXdSb3V0aW5nVGFibGUgPSBuZXdNdXgucm91dGluZ1RhYmxlO1xuICB2YXIgYWZmZWN0ZWRQaWRzID1cbiAgICAgIGNvbXB1dGVBZmZlY3RlZFBpZHMob2xkUm91dGluZ1RhYmxlLCBkZWx0YUFnZ3JlZ2F0ZU5vRWNobykuYWRkKGFjdGluZ1BpZCkucmVtb3ZlKFwibWV0YVwiKTtcbiAgcmV0dXJuIHtcbiAgICBldmVudE1hcDogSW1tdXRhYmxlLk1hcCgpLndpdGhNdXRhdGlvbnMoZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgYWZmZWN0ZWRQaWRzLmZvckVhY2goZnVuY3Rpb24gKHBpZCkge1xuXHR2YXIgcGF0Y2hGb3JQaWQ7XG5cdGlmIChwaWQgPT09IGFjdGluZ1BpZCkge1xuXHQgIHZhciBwYXJ0MSA9IG5ldyBQYXRjaC5QYXRjaChcblx0ICAgIGVjaG9DYW5jZWxsZWRUcmllKFBhdGNoLmJpYXNlZEludGVyc2VjdGlvbihuZXdSb3V0aW5nVGFibGUsIGRlbHRhLmFkZGVkKSksXG5cdCAgICBlY2hvQ2FuY2VsbGVkVHJpZShQYXRjaC5iaWFzZWRJbnRlcnNlY3Rpb24ob2xkUm91dGluZ1RhYmxlLCBkZWx0YS5yZW1vdmVkKSkpO1xuXHQgIHZhciBwYXJ0MiA9IG5ldyBQYXRjaC5QYXRjaChQYXRjaC5iaWFzZWRJbnRlcnNlY3Rpb24oZGVsdGFBZ2dyZWdhdGVOb0VjaG8uYWRkZWQsXG5cdFx0XHRcdFx0XHRcdCAgICAgICBuZXdNdXguaW50ZXJlc3RzT2YocGlkKSksXG5cdFx0XHRcdCAgICAgIFBhdGNoLmJpYXNlZEludGVyc2VjdGlvbihkZWx0YUFnZ3JlZ2F0ZU5vRWNoby5yZW1vdmVkLFxuXHRcdFx0XHRcdFx0XHQgICAgICAgb2xkTXV4LmludGVyZXN0c09mKHBpZCkpKTtcblx0ICBwYXRjaEZvclBpZCA9IHBhcnQxLnVuc2FmZVVuaW9uKHBhcnQyKTtcblx0fSBlbHNlIHtcblx0ICBwYXRjaEZvclBpZCA9IGRlbHRhQWdncmVnYXRlTm9FY2hvLnZpZXdGcm9tKG9sZE11eC5pbnRlcmVzdHNPZihwaWQpKTtcblx0fVxuXHRpZiAocGF0Y2hGb3JQaWQuaXNOb25FbXB0eSgpKSB7XG5cdCAgcmVzdWx0LnNldChwaWQsIHBhdGNoRm9yUGlkKTtcblx0fVxuICAgICAgfSk7XG4gICAgfSksXG4gICAgbWV0YUV2ZW50czogKGFjdGluZ1BpZCA9PT0gXCJtZXRhXCIpXG4gICAgICA/IEltbXV0YWJsZS5MaXN0KClcbiAgICAgIDogSW1tdXRhYmxlLkxpc3Qub2YoZGVsdGEuY29tcHV0ZUFnZ3JlZ2F0ZShhY3RpbmdQaWQsIG9sZFJvdXRpbmdUYWJsZSwgdHJ1ZSkuZHJvcCgpKVxuICB9O1xufVxuXG5mdW5jdGlvbiBjb21wdXRlQWZmZWN0ZWRQaWRzKHJvdXRpbmdUYWJsZSwgZGVsdGEpIHtcbiAgdmFyIGNvdmVyID0gUm91dGUuX3VuaW9uKGRlbHRhLmFkZGVkLCBkZWx0YS5yZW1vdmVkKTtcbiAgcm91dGluZ1RhYmxlID0gUm91dGUudHJpZVN0ZXAocm91dGluZ1RhYmxlLCBSb3V0ZS5TT0EpO1xuICByb3V0aW5nVGFibGUgPSBSb3V0ZS50cmllU3RlcChyb3V0aW5nVGFibGUsIFBhdGNoLiRPYnNlcnZlKTtcbiAgcmV0dXJuIFJvdXRlLm1hdGNoVHJpZShjb3Zlciwgcm91dGluZ1RhYmxlLCBJbW11dGFibGUuU2V0KCksXG5cdFx0XHQgZnVuY3Rpb24gKHYsIHIsIGFjYykge1xuXHRcdFx0ICAgcmV0dXJuIGFjYy51bmlvbihSb3V0ZS50cmllU3RlcChyLCBSb3V0ZS5FT0EpLnZhbHVlKTtcblx0XHRcdCB9KTtcbn1cblxuTXV4LnByb3RvdHlwZS5yb3V0ZU1lc3NhZ2UgPSBmdW5jdGlvbiAoYm9keSkge1xuICBpZiAoUm91dGUubWF0Y2hWYWx1ZSh0aGlzLnJvdXRpbmdUYWJsZSwgYm9keSkgPT09IG51bGwpIHtcbiAgICByZXR1cm4gUm91dGUubWF0Y2hWYWx1ZSh0aGlzLnJvdXRpbmdUYWJsZSwgUGF0Y2gub2JzZXJ2ZShib2R5KSkgfHwgSW1tdXRhYmxlLlNldCgpO1xuICB9IGVsc2Uge1xuICAgIC8vIFNvbWUgb3RoZXIgc3RyZWFtIGhhcyBkZWNsYXJlZCBib2R5XG4gICAgcmV0dXJuIEltbXV0YWJsZS5TZXQoKTtcbiAgfVxufTtcblxuTXV4LnByb3RvdHlwZS5pbnRlcmVzdHNPZiA9IGZ1bmN0aW9uIChwaWQpIHtcbiAgcmV0dXJuIHRoaXMuaW50ZXJlc3RUYWJsZS5nZXQocGlkLCBSb3V0ZS5lbXB0eVRyaWUpO1xufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbm1vZHVsZS5leHBvcnRzLk11eCA9IE11eDtcbm1vZHVsZS5leHBvcnRzLmNvbXB1dGVFdmVudHMgPSBjb21wdXRlRXZlbnRzO1xubW9kdWxlLmV4cG9ydHMuY29tcHV0ZUFmZmVjdGVkUGlkcyA9IGNvbXB1dGVBZmZlY3RlZFBpZHM7XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIFJvdXRlID0gcmVxdWlyZShcIi4vcm91dGUuanNcIik7XG52YXIgSW1tdXRhYmxlID0gcmVxdWlyZShcImltbXV0YWJsZVwiKTtcblxudmFyIF9fID0gUm91dGUuX187XG52YXIgXyQgPSBSb3V0ZS5fJDtcblxuZnVuY3Rpb24gUGF0Y2goYWRkZWQsIHJlbW92ZWQpIHtcbiAgdGhpcy5hZGRlZCA9IGFkZGVkO1xuICB0aGlzLnJlbW92ZWQgPSByZW1vdmVkO1xufVxuXG52YXIgZW1wdHlQYXRjaCA9IG5ldyBQYXRjaChSb3V0ZS5lbXB0eVRyaWUsIFJvdXRlLmVtcHR5VHJpZSk7XG52YXIgcmVtb3ZlRXZlcnl0aGluZ1BhdGNoID0gbmV3IFBhdGNoKFJvdXRlLmVtcHR5VHJpZSwgUm91dGUuY29tcGlsZVBhdHRlcm4odHJ1ZSwgX18pKTtcblxudmFyICRPYnNlcnZlID0gbmV3IFJvdXRlLiRTcGVjaWFsKFwiJE9ic2VydmVcIik7XG52YXIgJEF0TWV0YSA9IG5ldyBSb3V0ZS4kU3BlY2lhbChcIiRBdE1ldGFcIik7XG52YXIgJEFkdmVydGlzZSA9IG5ldyBSb3V0ZS4kU3BlY2lhbChcIiRBZHZlcnRpc2VcIik7XG5cbmZ1bmN0aW9uIG9ic2VydmUocCkgeyByZXR1cm4gWyRPYnNlcnZlLCBwXTsgfVxuZnVuY3Rpb24gYXRNZXRhKHApIHsgcmV0dXJuIFskQXRNZXRhLCBwXTsgfVxuZnVuY3Rpb24gYWR2ZXJ0aXNlKHApIHsgcmV0dXJuIFskQWR2ZXJ0aXNlLCBwXTsgfVxuXG5mdW5jdGlvbiBpc09ic2VydmUocCkgeyByZXR1cm4gcFswXSA9PT0gJE9ic2VydmU7IH1cbmZ1bmN0aW9uIGlzQXRNZXRhKHApIHsgcmV0dXJuIHBbMF0gPT09ICRBdE1ldGE7IH1cbmZ1bmN0aW9uIGlzQWR2ZXJ0aXNlKHApIHsgcmV0dXJuIHBbMF0gPT09ICRBZHZlcnRpc2U7IH1cblxuZnVuY3Rpb24gcHJlcGVuZEF0TWV0YShwLCBsZXZlbCkge1xuICB3aGlsZSAobGV2ZWwtLSkge1xuICAgIHAgPSBhdE1ldGEocCk7XG4gIH1cbiAgcmV0dXJuIHA7XG59XG5cbmZ1bmN0aW9uIHN0cmlwQXRNZXRhKHAsIGxldmVsKSB7XG4gIHdoaWxlIChsZXZlbC0tKSB7XG4gICAgaWYgKHAubGVuZ3RoID09PSAyICYmIHBbMF0gPT09ICRBdE1ldGEpIHtcbiAgICAgIHAgPSBwWzFdO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHA7XG59XG5cbmZ1bmN0aW9uIG9ic2VydmVBdE1ldGEocCwgbGV2ZWwpIHtcbiAgaWYgKGxldmVsID09PSAwKSB7XG4gICAgcmV0dXJuIFJvdXRlLmNvbXBpbGVQYXR0ZXJuKHRydWUsIG9ic2VydmUocCkpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBSb3V0ZS5fdW5pb24oXG4gICAgICBSb3V0ZS5jb21waWxlUGF0dGVybih0cnVlLCBvYnNlcnZlKHByZXBlbmRBdE1ldGEocCwgbGV2ZWwpKSksXG4gICAgICBSb3V0ZS5jb21waWxlUGF0dGVybih0cnVlLCBhdE1ldGEoUm91dGUuZW1iZWRkZWRUcmllKG9ic2VydmVBdE1ldGEocCwgbGV2ZWwgLSAxKSkpKSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gX2NoZWNrKHApIHtcbiAgaWYgKHAgaW5zdGFuY2VvZiBQYXRjaCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBjb25zdHJ1Y3QgcGF0Y2ggcGF0dGVybiB1c2luZyBhbiBlbWJlZGRlZCBwYXRjaFwiKTtcbiAgfVxuICByZXR1cm4gcDtcbn1cblxuZnVuY3Rpb24gYXNzZXJ0KHAsIG1ldGFMZXZlbCkge1xuICByZXR1cm4gbmV3IFBhdGNoKFJvdXRlLmNvbXBpbGVQYXR0ZXJuKHRydWUsIHByZXBlbmRBdE1ldGEoX2NoZWNrKHApLCBtZXRhTGV2ZWwgfHwgMCkpLFxuXHRcdCAgIFJvdXRlLmVtcHR5VHJpZSk7XG59XG5cbmZ1bmN0aW9uIHJldHJhY3QocCwgbWV0YUxldmVsKSB7XG4gIHJldHVybiBuZXcgUGF0Y2goUm91dGUuZW1wdHlUcmllLFxuXHRcdCAgIFJvdXRlLmNvbXBpbGVQYXR0ZXJuKHRydWUsIHByZXBlbmRBdE1ldGEoX2NoZWNrKHApLCBtZXRhTGV2ZWwgfHwgMCkpKTtcbn1cblxuZnVuY3Rpb24gc3ViKHAsIG1ldGFMZXZlbCkge1xuICByZXR1cm4gbmV3IFBhdGNoKG9ic2VydmVBdE1ldGEoX2NoZWNrKHApLCBtZXRhTGV2ZWwgfHwgMCksIFJvdXRlLmVtcHR5VHJpZSk7XG59XG5cbmZ1bmN0aW9uIHVuc3ViKHAsIG1ldGFMZXZlbCkge1xuICByZXR1cm4gbmV3IFBhdGNoKFJvdXRlLmVtcHR5VHJpZSwgb2JzZXJ2ZUF0TWV0YShfY2hlY2socCksIG1ldGFMZXZlbCB8fCAwKSk7XG59XG5cbmZ1bmN0aW9uIHB1YihwLCBtZXRhTGV2ZWwpIHtcbiAgcmV0dXJuIGFzc2VydChhZHZlcnRpc2UoX2NoZWNrKHApKSwgbWV0YUxldmVsKTtcbn1cblxuZnVuY3Rpb24gdW5wdWIocCwgbWV0YUxldmVsKSB7XG4gIHJldHVybiByZXRyYWN0KGFkdmVydGlzZShfY2hlY2socCkpLCBtZXRhTGV2ZWwpO1xufVxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuUGF0Y2gucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChvdGhlcikge1xuICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFBhdGNoKSkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gSW1tdXRhYmxlLmlzKHRoaXMuYWRkZWQsIG90aGVyLmFkZGVkKSAmJiBJbW11dGFibGUuaXModGhpcy5yZW1vdmVkLCBvdGhlci5yZW1vdmVkKTtcbn07XG5cblBhdGNoLnByb3RvdHlwZS5pc0VtcHR5ID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5hZGRlZCA9PT0gUm91dGUuZW1wdHlUcmllICYmIHRoaXMucmVtb3ZlZCA9PT0gUm91dGUuZW1wdHlUcmllO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLmlzTm9uRW1wdHkgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAhdGhpcy5pc0VtcHR5KCk7XG59O1xuXG5QYXRjaC5wcm90b3R5cGUuaGFzQWRkZWQgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLmFkZGVkICE9PSBSb3V0ZS5lbXB0eVRyaWU7XG59O1xuXG5QYXRjaC5wcm90b3R5cGUuaGFzUmVtb3ZlZCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMucmVtb3ZlZCAhPT0gUm91dGUuZW1wdHlUcmllO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLmxpZnQgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBuZXcgUGF0Y2goUm91dGUuY29tcGlsZVBhdHRlcm4odHJ1ZSwgYXRNZXRhKFJvdXRlLmVtYmVkZGVkVHJpZSh0aGlzLmFkZGVkKSkpLFxuXHRcdCAgIFJvdXRlLmNvbXBpbGVQYXR0ZXJuKHRydWUsIGF0TWV0YShSb3V0ZS5lbWJlZGRlZFRyaWUodGhpcy5yZW1vdmVkKSkpKTtcbn07XG5cbnZhciBhdE1ldGFQcm9qID0gUm91dGUuY29tcGlsZVByb2plY3Rpb24oYXRNZXRhKF8kKSk7XG5QYXRjaC5wcm90b3R5cGUuZHJvcCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIG5ldyBQYXRjaChSb3V0ZS5wcm9qZWN0KHRoaXMuYWRkZWQsIGF0TWV0YVByb2opLFxuXHRcdCAgIFJvdXRlLnByb2plY3QodGhpcy5yZW1vdmVkLCBhdE1ldGFQcm9qKSk7XG59O1xuXG5QYXRjaC5wcm90b3R5cGUuc3RyaXAgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBuZXcgUGF0Y2goUm91dGUucmVsYWJlbCh0aGlzLmFkZGVkLCBmdW5jdGlvbiAodikgeyByZXR1cm4gdHJ1ZTsgfSksXG5cdFx0ICAgUm91dGUucmVsYWJlbCh0aGlzLnJlbW92ZWQsIGZ1bmN0aW9uICh2KSB7IHJldHVybiB0cnVlOyB9KSk7XG59O1xuXG5QYXRjaC5wcm90b3R5cGUubGFiZWwgPSBmdW5jdGlvbiAobGFiZWxWYWx1ZSkge1xuICByZXR1cm4gbmV3IFBhdGNoKFJvdXRlLnJlbGFiZWwodGhpcy5hZGRlZCwgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIGxhYmVsVmFsdWU7IH0pLFxuXHRcdCAgIFJvdXRlLnJlbGFiZWwodGhpcy5yZW1vdmVkLCBmdW5jdGlvbiAodikgeyByZXR1cm4gbGFiZWxWYWx1ZTsgfSkpO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLmxpbWl0ID0gZnVuY3Rpb24gKGJvdW5kKSB7XG4gIHJldHVybiBuZXcgUGF0Y2goUm91dGUuc3VidHJhY3QodGhpcy5hZGRlZCwgYm91bmQsIGZ1bmN0aW9uICh2MSwgdjIpIHsgcmV0dXJuIG51bGw7IH0pLFxuXHRcdCAgIFJvdXRlLmludGVyc2VjdCh0aGlzLnJlbW92ZWQsIGJvdW5kLCBmdW5jdGlvbiAodjEsIHYyKSB7IHJldHVybiB2MTsgfSkpO1xufTtcblxudmFyIG1ldGFMYWJlbFNldCA9IEltbXV0YWJsZS5TZXQoW1wibWV0YVwiXSk7XG5QYXRjaC5wcm90b3R5cGUuY29tcHV0ZUFnZ3JlZ2F0ZSA9IGZ1bmN0aW9uIChsYWJlbCwgYmFzZSwgcmVtb3ZlTWV0YSAvKiBvcHRpb25hbCBmbGFnICovKSB7XG4gIHJldHVybiBuZXcgUGF0Y2goUm91dGUuc3VidHJhY3QodGhpcy5hZGRlZCwgYmFzZSwgYWRkQ29tYmluZXIpLFxuXHRcdCAgIFJvdXRlLnN1YnRyYWN0KHRoaXMucmVtb3ZlZCwgYmFzZSwgcmVtb3ZlQ29tYmluZXIpKTtcblxuICBmdW5jdGlvbiBhZGRDb21iaW5lcih2MSwgdjIpIHtcbiAgICBpZiAocmVtb3ZlTWV0YSAmJiBJbW11dGFibGUuaXModjIsIG1ldGFMYWJlbFNldCkpIHtcbiAgICAgIHJldHVybiB2MTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVtb3ZlQ29tYmluZXIodjEsIHYyKSB7XG4gICAgaWYgKHYyLnNpemUgPT09IDEpIHtcbiAgICAgIHJldHVybiB2MTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHJlbW92ZU1ldGEgJiYgdjIuc2l6ZSA9PT0gMiAmJiB2Mi5oYXMoXCJtZXRhXCIpKSB7XG5cdHJldHVybiB2MTtcbiAgICAgIH0gZWxzZSB7XG5cdHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuUGF0Y2gucHJvdG90eXBlLmFwcGx5VG8gPSBmdW5jdGlvbiAoYmFzZSkge1xuICByZXR1cm4gUm91dGUuX3VuaW9uKFJvdXRlLnN1YnRyYWN0KGJhc2UsIHRoaXMucmVtb3ZlZCksIHRoaXMuYWRkZWQpO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLnVwZGF0ZUludGVyZXN0cyA9IGZ1bmN0aW9uIChiYXNlKSB7XG4gIHJldHVybiBSb3V0ZS5fdW5pb24oUm91dGUuc3VidHJhY3QoYmFzZSwgdGhpcy5yZW1vdmVkLCBmdW5jdGlvbiAodjEsIHYyKSB7IHJldHVybiBudWxsOyB9KSxcblx0XHQgICAgICB0aGlzLmFkZGVkLFxuXHRcdCAgICAgIGZ1bmN0aW9uICh2MSwgdjIpIHsgcmV0dXJuIHRydWU7IH0pO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLnVuYXBwbHlUbyA9IGZ1bmN0aW9uIChiYXNlKSB7XG4gIHJldHVybiBSb3V0ZS5fdW5pb24oUm91dGUuc3VidHJhY3QoYmFzZSwgdGhpcy5hZGRlZCksIHRoaXMucmVtb3ZlZCk7XG59O1xuXG5QYXRjaC5wcm90b3R5cGUuYW5kVGhlbiA9IGZ1bmN0aW9uIChuZXh0UGF0Y2gpIHtcbiAgcmV0dXJuIG5ldyBQYXRjaChuZXh0UGF0Y2gudXBkYXRlSW50ZXJlc3RzKHRoaXMuYWRkZWQpLFxuXHRcdCAgIFJvdXRlLl91bmlvbihSb3V0ZS5zdWJ0cmFjdCh0aGlzLnJlbW92ZWQsXG5cdFx0XHRcdFx0ICAgICAgIG5leHRQYXRjaC5hZGRlZCxcblx0XHRcdFx0XHQgICAgICAgZnVuY3Rpb24gKHYxLCB2MikgeyByZXR1cm4gbnVsbDsgfSksXG5cdFx0XHRcdG5leHRQYXRjaC5yZW1vdmVkLFxuXHRcdFx0XHRmdW5jdGlvbiAodjEsIHYyKSB7IHJldHVybiB0cnVlOyB9KSk7XG59O1xuXG5mdW5jdGlvbiBwYXRjaFNlcSgvKiBwYXRjaCwgcGF0Y2gsIC4uLiAqLykge1xuICB2YXIgcCA9IGVtcHR5UGF0Y2g7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgcCA9IHAuYW5kVGhlbihhcmd1bWVudHNbaV0pO1xuICB9XG4gIHJldHVybiBwO1xufVxuXG5mdW5jdGlvbiBjb21wdXRlUGF0Y2gob2xkQmFzZSwgbmV3QmFzZSkge1xuICByZXR1cm4gbmV3IFBhdGNoKFJvdXRlLnN1YnRyYWN0KG5ld0Jhc2UsIG9sZEJhc2UpLFxuXHRcdCAgIFJvdXRlLnN1YnRyYWN0KG9sZEJhc2UsIG5ld0Jhc2UpKTtcbn1cblxuZnVuY3Rpb24gYmlhc2VkSW50ZXJzZWN0aW9uKG9iamVjdCwgc3ViamVjdCkge1xuICBzdWJqZWN0ID0gUm91dGUudHJpZVN0ZXAoc3ViamVjdCwgUm91dGUuU09BKTtcbiAgc3ViamVjdCA9IFJvdXRlLnRyaWVTdGVwKHN1YmplY3QsICRPYnNlcnZlKTtcbiAgcmV0dXJuIFJvdXRlLmludGVyc2VjdChvYmplY3QsIHN1YmplY3QsXG5cdFx0XHQgZnVuY3Rpb24gKHYxLCB2MikgeyByZXR1cm4gdHJ1ZTsgfSxcblx0XHRcdCBmdW5jdGlvbiAodiwgcikgeyByZXR1cm4gUm91dGUudHJpZVN0ZXAociwgUm91dGUuRU9BKTsgfSk7XG59XG5cblBhdGNoLnByb3RvdHlwZS52aWV3RnJvbSA9IGZ1bmN0aW9uIChpbnRlcmVzdHMpIHtcbiAgcmV0dXJuIG5ldyBQYXRjaChiaWFzZWRJbnRlcnNlY3Rpb24odGhpcy5hZGRlZCwgaW50ZXJlc3RzKSxcblx0XHQgICBiaWFzZWRJbnRlcnNlY3Rpb24odGhpcy5yZW1vdmVkLCBpbnRlcmVzdHMpKTtcbn07XG5cblBhdGNoLnByb3RvdHlwZS51bnNhZmVVbmlvbiA9IGZ1bmN0aW9uIChvdGhlcikge1xuICAvLyBVbnNhZmUgYmVjYXVzZSBkb2VzIG5vdCBuZWNlc3NhcmlseSBwcmVzZXJ2ZSBpbnZhcmlhbnQgdGhhdCBhZGRlZFxuICAvLyBhbmQgcmVtb3ZlZCBhcmUgZGlzam9pbnQuXG4gIHJldHVybiBuZXcgUGF0Y2goUm91dGUuX3VuaW9uKHRoaXMuYWRkZWQsIG90aGVyLmFkZGVkKSxcblx0XHQgICBSb3V0ZS5fdW5pb24odGhpcy5yZW1vdmVkLCBvdGhlci5yZW1vdmVkKSk7XG59O1xuXG5QYXRjaC5wcm90b3R5cGUucHJvamVjdCA9IGZ1bmN0aW9uIChjb21waWxlZFByb2plY3Rpb24pIHtcbiAgcmV0dXJuIG5ldyBQYXRjaChSb3V0ZS5wcm9qZWN0KHRoaXMuYWRkZWQsIGNvbXBpbGVkUHJvamVjdGlvbiksXG5cdFx0ICAgUm91dGUucHJvamVjdCh0aGlzLnJlbW92ZWQsIGNvbXBpbGVkUHJvamVjdGlvbikpO1xufTtcblxuUGF0Y2gucHJvdG90eXBlLnByb2plY3RPYmplY3RzID0gZnVuY3Rpb24gKGNvbXBpbGVkUHJvamVjdGlvbikge1xuICByZXR1cm4gW1JvdXRlLnByb2plY3RPYmplY3RzKHRoaXMuYWRkZWQsIGNvbXBpbGVkUHJvamVjdGlvbiksXG5cdCAgUm91dGUucHJvamVjdE9iamVjdHModGhpcy5yZW1vdmVkLCBjb21waWxlZFByb2plY3Rpb24pXTtcbn07XG5cblBhdGNoLnByb3RvdHlwZS5wcmV0dHkgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAoXCI8PDw8PDw8PCBSZW1vdmVkOlxcblwiICsgUm91dGUucHJldHR5VHJpZSh0aGlzLnJlbW92ZWQpICsgXCJcXG5cIiArXG5cdCAgXCI9PT09PT09PSBBZGRlZDpcXG5cIiArIFJvdXRlLnByZXR0eVRyaWUodGhpcy5hZGRlZCkgKyBcIlxcblwiICtcblx0ICBcIj4+Pj4+Pj4+XCIpO1xufVxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxubW9kdWxlLmV4cG9ydHMuUGF0Y2ggPSBQYXRjaDtcbm1vZHVsZS5leHBvcnRzLmVtcHR5UGF0Y2ggPSBlbXB0eVBhdGNoO1xubW9kdWxlLmV4cG9ydHMucmVtb3ZlRXZlcnl0aGluZ1BhdGNoID0gcmVtb3ZlRXZlcnl0aGluZ1BhdGNoO1xuXG5tb2R1bGUuZXhwb3J0cy4kT2JzZXJ2ZSA9ICRPYnNlcnZlO1xubW9kdWxlLmV4cG9ydHMuJEF0TWV0YSA9ICRBdE1ldGE7XG5tb2R1bGUuZXhwb3J0cy4kQWR2ZXJ0aXNlID0gJEFkdmVydGlzZTtcbm1vZHVsZS5leHBvcnRzLm9ic2VydmUgPSBvYnNlcnZlO1xubW9kdWxlLmV4cG9ydHMuYXRNZXRhID0gYXRNZXRhO1xubW9kdWxlLmV4cG9ydHMuYWR2ZXJ0aXNlID0gYWR2ZXJ0aXNlO1xubW9kdWxlLmV4cG9ydHMuaXNPYnNlcnZlID0gaXNPYnNlcnZlO1xubW9kdWxlLmV4cG9ydHMuaXNBdE1ldGEgPSBpc0F0TWV0YTtcbm1vZHVsZS5leHBvcnRzLmlzQWR2ZXJ0aXNlID0gaXNBZHZlcnRpc2U7XG5cbm1vZHVsZS5leHBvcnRzLnByZXBlbmRBdE1ldGEgPSBwcmVwZW5kQXRNZXRhO1xubW9kdWxlLmV4cG9ydHMuc3RyaXBBdE1ldGEgPSBzdHJpcEF0TWV0YTtcbm1vZHVsZS5leHBvcnRzLm9ic2VydmVBdE1ldGEgPSBvYnNlcnZlQXRNZXRhO1xubW9kdWxlLmV4cG9ydHMuYXNzZXJ0ID0gYXNzZXJ0O1xubW9kdWxlLmV4cG9ydHMucmV0cmFjdCA9IHJldHJhY3Q7XG5tb2R1bGUuZXhwb3J0cy5zdWIgPSBzdWI7XG5tb2R1bGUuZXhwb3J0cy51bnN1YiA9IHVuc3ViO1xubW9kdWxlLmV4cG9ydHMucHViID0gcHViO1xubW9kdWxlLmV4cG9ydHMudW5wdWIgPSB1bnB1YjtcblxubW9kdWxlLmV4cG9ydHMucGF0Y2hTZXEgPSBwYXRjaFNlcTtcbm1vZHVsZS5leHBvcnRzLmNvbXB1dGVQYXRjaCA9IGNvbXB1dGVQYXRjaDtcbm1vZHVsZS5leHBvcnRzLmJpYXNlZEludGVyc2VjdGlvbiA9IGJpYXNlZEludGVyc2VjdGlvbjtcbiIsInZhciByYW5kb21JZDtcblxuaWYgKCh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykgJiZcbiAgICAodHlwZW9mIHdpbmRvdy5jcnlwdG8gIT09ICd1bmRlZmluZWQnKSAmJlxuICAgICh0eXBlb2Ygd2luZG93LmNyeXB0by5nZXRSYW5kb21WYWx1ZXMgIT09ICd1bmRlZmluZWQnKSkge1xuICByYW5kb21JZCA9IGZ1bmN0aW9uIChieXRlQ291bnQpIHtcbiAgICB2YXIgYnVmID0gbmV3IFVpbnQ4QXJyYXkoYnl0ZUNvdW50KTtcbiAgICB3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhidWYpO1xuICAgIHJldHVybiBidG9hKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgYnVmKSkucmVwbGFjZSgvPS9nLCcnKTtcbiAgfTtcbn0gZWxzZSB7XG4gIHZhciBjcnlwdG87XG4gIHRyeSB7XG4gICAgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG4gIH0gY2F0Y2ggKGUpIHt9XG4gIGlmICgodHlwZW9mIGNyeXB0byAhPT0gJ3VuZGVmaW5lZCcpICYmXG4gICAgICAodHlwZW9mIGNyeXB0by5yYW5kb21CeXRlcyAhPT0gJ3VuZGVmaW5lZCcpKSB7XG4gICAgcmFuZG9tSWQgPSBmdW5jdGlvbiAoYnl0ZUNvdW50KSB7XG4gICAgICByZXR1cm4gY3J5cHRvLnJhbmRvbUJ5dGVzKGJ5dGVDb3VudCkuYmFzZTY0U2xpY2UoKS5yZXBsYWNlKC89L2csJycpO1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgY29uc29sZS53YXJuKCdObyBzdWl0YWJsZSBpbXBsZW1lbnRhdGlvbiBmb3IgUmFuZG9tSUQucmFuZG9tSWQgYXZhaWxhYmxlLicpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzLnJhbmRvbUlkID0gcmFuZG9tSWQ7XG4iLCJcInVzZSBzdHJpY3RcIjtcblxuLy8gUmVmbGVjdGlvbiBvbiBmdW5jdGlvbiBmb3JtYWwgcGFyYW1ldGVyIGxpc3RzLlxuLy8gVGhpcyBtb2R1bGUgaXMgYmFzZWQgb24gQW5ndWxhcidzIFwiaW5qZWN0b3JcIiBjb2RlLFxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci5qcy9ibG9iL21hc3Rlci9zcmMvYXV0by9pbmplY3Rvci5qcyxcbi8vIE1JVCBsaWNlbnNlZCwgYW5kIGhlbmNlOlxuLy8gQ29weXJpZ2h0IChjKSAyMDEwLTIwMTQgR29vZ2xlLCBJbmMuIGh0dHA6Ly9hbmd1bGFyanMub3JnXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTQgVG9ueSBHYXJub2NrLUpvbmVzXG5cbnZhciBGTl9BUkdTID0gL15mdW5jdGlvblxccypbXlxcKF0qXFwoXFxzKihbXlxcKV0qKVxcKS9tO1xudmFyIEZOX0FSR19TUExJVCA9IC8sLztcbnZhciBTVFJJUF9DT01NRU5UUyA9IC8oKFxcL1xcLy4qJCl8KFxcL1xcKltcXHNcXFNdKj9cXCpcXC8pKS9tZztcblxuZnVuY3Rpb24gZm9ybWFsUGFyYW1ldGVycyhmbikge1xuICAgIHZhciByZXN1bHQgPSBbXTtcblxuICAgIHZhciBmblRleHQgPSBmbi50b1N0cmluZygpLnJlcGxhY2UoU1RSSVBfQ09NTUVOVFMsICcnKTtcbiAgICB2YXIgYXJnRGVjbCA9IGZuVGV4dC5tYXRjaChGTl9BUkdTKTtcbiAgICB2YXIgYXJncyA9IGFyZ0RlY2xbMV0uc3BsaXQoRk5fQVJHX1NQTElUKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcblx0dmFyIHRyaW1tZWQgPSBhcmdzW2ldLnRyaW0oKTtcblx0aWYgKHRyaW1tZWQpIHsgcmVzdWx0LnB1c2godHJpbW1lZCk7IH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cy5mb3JtYWxQYXJhbWV0ZXJzID0gZm9ybWFsUGFyYW1ldGVycztcbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgSW1tdXRhYmxlID0gcmVxdWlyZShcImltbXV0YWJsZVwiKTtcblxuZnVuY3Rpb24gbWFrZVN0cnVjdHVyZUNvbnN0cnVjdG9yKGxhYmVsLCBhcmd1bWVudE5hbWVzKSB7XG4gIHZhciAkU3luZGljYXRlTWV0YSQgPSB7XG4gICAgbGFiZWw6IGxhYmVsLFxuICAgIGFyZ3VtZW50czogYXJndW1lbnROYW1lc1xuICB9O1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHJlc3VsdCA9IHtcIiRTeW5kaWNhdGVNZXRhJFwiOiAkU3luZGljYXRlTWV0YSR9O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnROYW1lcy5sZW5ndGg7IGkrKykge1xuICAgICAgcmVzdWx0W2FyZ3VtZW50TmFtZXNbaV1dID0gYXJndW1lbnRzW2ldO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xufVxuXG5mdW5jdGlvbiBpc1N0cnVjdHVyZShzKSB7XG4gIHJldHVybiAocyAhPT0gbnVsbCkgJiYgKHR5cGVvZiBzID09PSAnb2JqZWN0JykgJiYgKFwiJFN5bmRpY2F0ZU1ldGEkXCIgaW4gcyk7XG59XG5cbmZ1bmN0aW9uIHN0cnVjdHVyZVRvQXJyYXkocykge1xuICB2YXIgcmVzdWx0ID0gW3MuJFN5bmRpY2F0ZU1ldGEkLmxhYmVsXTtcbiAgdmFyIGFyZ3MgPSBzLiRTeW5kaWNhdGVNZXRhJC5hcmd1bWVudHM7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuICAgIHJlc3VsdC5wdXNoKHNbYXJnc1tpXV0pO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uICRTcGVjaWFsKG5hbWUpIHtcbiAgdGhpcy5uYW1lID0gbmFtZTtcbn1cblxudmFyIF9fID0gbmV3ICRTcGVjaWFsKFwid2lsZGNhcmRcIik7IC8qIHdpbGRjYXJkIG1hcmtlciAqL1xuXG52YXIgU09BID0gbmV3ICRTcGVjaWFsKFwiW1wiKTsgLy8gc3RhcnQgb2YgYXJyYXlcbnZhciBFT0EgPSBuZXcgJFNwZWNpYWwoXCJdXCIpOyAvLyBlbmQgb2YgYXJyYXlcblxuZnVuY3Rpb24gZGllKG1lc3NhZ2UpIHtcbiAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xufVxuXG5mdW5jdGlvbiAkRW1iZWRkZWQodHJpZSkge1xuICB0aGlzLnRyaWUgPSB0cmllO1xufVxuXG5mdW5jdGlvbiBlbWJlZGRlZFRyaWUodHJpZSkge1xuICByZXR1cm4gbmV3ICRFbWJlZGRlZCh0cmllKTtcbn1cblxuLy8gVGhlIG5hbWUgYXJndW1lbnQgc2hvdWxkIGJlIGEgc3RyaW5nIG9yIG51bGw7IGl0IGRlZmF1bHRzIHRvIG51bGwuXG4vLyBUaGUgcGF0dGVybiBhcmd1bWVudCBkZWZhdWx0cyB0byB3aWxkY2FyZCwgX18uXG5mdW5jdGlvbiAkQ2FwdHVyZShuYW1lLCBwYXR0ZXJuKSB7XG4gIHRoaXMubmFtZSA9IG5hbWUgfHwgbnVsbDtcbiAgdGhpcy5wYXR0ZXJuID0gKHR5cGVvZiBwYXR0ZXJuID09PSAndW5kZWZpbmVkJyA/IF9fIDogcGF0dGVybik7XG59XG5cbi8vIEFiYnJldmlhdGlvbjogXyQoLi4uKSA8PT0+IG5ldyAkQ2FwdHVyZSguLi4pXG5mdW5jdGlvbiBfJChuYW1lLCBwYXR0ZXJuKSB7XG4gIHJldHVybiBuZXcgJENhcHR1cmUobmFtZSwgcGF0dGVybik7XG59XG5cbmZ1bmN0aW9uIGlzQ2FwdHVyZSh4KSB7IHJldHVybiB4IGluc3RhbmNlb2YgJENhcHR1cmUgfHwgeCA9PT0gXyQ7IH1cbmZ1bmN0aW9uIGNhcHR1cmVOYW1lKHgpIHsgcmV0dXJuIHggaW5zdGFuY2VvZiAkQ2FwdHVyZSA/IHgubmFtZSA6IG51bGw7IH1cbmZ1bmN0aW9uIGNhcHR1cmVQYXR0ZXJuKHgpIHsgcmV0dXJuIHggaW5zdGFuY2VvZiAkQ2FwdHVyZSA/IHgucGF0dGVybiA6IF9fOyB9XG5cbnZhciBTT0MgPSBuZXcgJFNwZWNpYWwoXCJ7XCIpOyAvLyBzdGFydCBvZiBjYXB0dXJlXG52YXIgRU9DID0gbmV3ICRTcGVjaWFsKFwifVwiKTsgLy8gZW5kIG9mIGNhcHR1cmVcblxuZnVuY3Rpb24gJFN1Y2Nlc3ModmFsdWUpIHtcbiAgdGhpcy52YWx1ZSA9IHZhbHVlO1xufVxuXG4kU3VjY2Vzcy5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gKG90aGVyKSB7XG4gIGlmICghKG90aGVyIGluc3RhbmNlb2YgJFN1Y2Nlc3MpKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiBJbW11dGFibGUuaXModGhpcy52YWx1ZSwgb3RoZXIudmFsdWUpO1xufTtcblxuZnVuY3Rpb24gJFdpbGRjYXJkU2VxdWVuY2UodHJpZSkge1xuICB0aGlzLnRyaWUgPSB0cmllO1xufVxuXG4kV2lsZGNhcmRTZXF1ZW5jZS5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gKG90aGVyKSB7XG4gIGlmICghKG90aGVyIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiBJbW11dGFibGUuaXModGhpcy50cmllLCBvdGhlci50cmllKTtcbn07XG5cbmZ1bmN0aW9uIGlzX2VtcHR5VHJpZShtKSB7XG4gIHJldHVybiBJbW11dGFibGUuaXMobSwgZW1wdHlUcmllKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBDb25zdHJ1Y3RvcnNcblxudmFyIGVtcHR5VHJpZSA9IEltbXV0YWJsZS5NYXAoKTtcblxuZnVuY3Rpb24gcnN1Y2Nlc3Modikge1xuICByZXR1cm4gKHYgPT09IG51bGwpID8gZW1wdHlUcmllIDogbmV3ICRTdWNjZXNzKHYpO1xufVxuXG5mdW5jdGlvbiByc2VxKGUsIHIpIHtcbiAgaWYgKHIgPT09IGVtcHR5VHJpZSkgcmV0dXJuIGVtcHR5VHJpZTtcbiAgcmV0dXJuIGVtcHR5VHJpZS5zZXQoZSwgcik7XG59XG5cbmZ1bmN0aW9uIHJ3aWxkKHIpIHtcbiAgcmV0dXJuIHJzZXEoX18sIHIpO1xufVxuXG5mdW5jdGlvbiByd2lsZHNlcShyKSB7XG4gIHJldHVybiAociA9PT0gZW1wdHlUcmllKSA/IGVtcHR5VHJpZSA6IG5ldyAkV2lsZGNhcmRTZXF1ZW5jZShyKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGNvbXBpbGVQYXR0ZXJuKHYsIHApIHtcbiAgaWYgKCFwKSBkaWUoXCJjb21waWxlUGF0dGVybjogbWlzc2luZyBwYXR0ZXJuXCIpO1xuICByZXR1cm4gd2FsayhwLCByc2VxKEVPQSwgcnN1Y2Nlc3ModikpKTtcblxuICBmdW5jdGlvbiB3YWxrKHAsIGFjYykge1xuICAgIGlmIChwID09PSBfXykgcmV0dXJuIHJ3aWxkKGFjYyk7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShwKSkge1xuICAgICAgYWNjID0gcnNlcShFT0EsIGFjYyk7XG4gICAgICBmb3IgKHZhciBpID0gcC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuXHRhY2MgPSB3YWxrKHBbaV0sIGFjYyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcnNlcShTT0EsIGFjYyk7XG4gICAgfVxuXG4gICAgaWYgKEltbXV0YWJsZS5MaXN0LmlzTGlzdChwKSkge1xuICAgICAgYWNjID0gcnNlcShFT0EsIGFjYyk7XG4gICAgICBwLnJldmVyc2UoKS5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtZW50KSB7XG5cdGFjYyA9IHdhbGsoZWxlbWVudCwgYWNjKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJzZXEoU09BLCBhY2MpO1xuICAgIH1cblxuICAgIGlmIChpc1N0cnVjdHVyZShwKSkge1xuICAgICAgdmFyIGFyZ3MgPSBwLiRTeW5kaWNhdGVNZXRhJC5hcmd1bWVudHM7XG4gICAgICBhY2MgPSByc2VxKEVPQSwgYWNjKTtcbiAgICAgIGZvciAodmFyIGkgPSBhcmdzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGFjYyA9IHdhbGsocFthcmdzW2ldXSwgYWNjKTtcbiAgICAgIH1cbiAgICAgIGFjYyA9IHJzZXEocC4kU3luZGljYXRlTWV0YSQubGFiZWwsIGFjYyk7XG4gICAgICByZXR1cm4gcnNlcShTT0EsIGFjYyk7XG4gICAgfVxuXG4gICAgaWYgKHAgaW5zdGFuY2VvZiAkRW1iZWRkZWQpIHtcbiAgICAgIHJldHVybiBhcHBlbmRUcmllKHAudHJpZSwgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIGFjYzsgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiByc2VxKHAsIGFjYyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG1hdGNoUGF0dGVybih2LCBwKSB7XG4gIHZhciBjYXB0dXJlQ291bnQgPSAwO1xuICB2YXIgcmVzdWx0ID0ge307XG4gIHRyeSB7XG4gICAgd2Fsayh2LCBwKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlmIChlLm1hdGNoUGF0dGVybkZhaWxlZCkgcmV0dXJuIG51bGw7XG4gICAgdGhyb3cgZTtcbiAgfVxuICByZXN1bHQubGVuZ3RoID0gY2FwdHVyZUNvdW50O1xuICByZXR1cm4gcmVzdWx0O1xuXG4gIGZ1bmN0aW9uIHdhbGsodiwgcCkge1xuICAgIGlmIChwID09PSB2KSByZXR1cm47XG5cbiAgICBpZiAocCA9PT0gX18pIHJldHVybjtcblxuICAgIGlmIChpc1N0cnVjdHVyZShwKSkgeyBwID0gc3RydWN0dXJlVG9BcnJheShwKTsgfVxuICAgIGlmIChpc1N0cnVjdHVyZSh2KSkgeyB2ID0gc3RydWN0dXJlVG9BcnJheSh2KTsgfVxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkocCkgJiYgQXJyYXkuaXNBcnJheSh2KSAmJiBwLmxlbmd0aCA9PT0gdi5sZW5ndGgpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuICAgICAgICB3YWxrKHZbaV0sIHBbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChpc0NhcHR1cmUocCkpIHtcbiAgICAgIHZhciB0aGlzQ2FwdHVyZSA9IGNhcHR1cmVDb3VudCsrO1xuICAgICAgd2Fsayh2LCBjYXB0dXJlUGF0dGVybihwKSk7XG4gICAgICByZXN1bHRbY2FwdHVyZU5hbWUocCkgfHwgKCckJyArIHRoaXNDYXB0dXJlKV0gPSB2O1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChwIGluc3RhbmNlb2YgJEVtYmVkZGVkKSB7XG4gICAgICBkaWUoXCIkRW1iZWRkZWQgcGF0dGVybnMgbm90IHN1cHBvcnRlZCBpbiBtYXRjaFBhdHRlcm4oKVwiKTtcbiAgICB9XG5cbiAgICB0aHJvdyB7bWF0Y2hQYXR0ZXJuRmFpbGVkOiB0cnVlfTtcbiAgfVxufVxuXG5mdW5jdGlvbiBydXBkYXRlKHIsIGtleSwgaykge1xuICB2YXIgb2xkV2lsZCA9IHIuZ2V0KF9fLCBlbXB0eVRyaWUpO1xuICBpZiAoSW1tdXRhYmxlLmlzKGssIG9sZFdpbGQpKSB7XG4gICAgcmV0dXJuIHIucmVtb3ZlKGtleSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHIuc2V0KGtleSwgayk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmxvb2t1cChyLCBrZXkpIHtcbiAgcmV0dXJuIHIuZ2V0KGtleSwgZW1wdHlUcmllKTtcbn1cblxuZnVuY3Rpb24gcmxvb2t1cFdpbGQociwga2V5KSB7XG4gIHZhciByZXN1bHQgPSByLmdldChrZXksIGZhbHNlKTtcbiAgaWYgKHJlc3VsdCkgcmV0dXJuIHJlc3VsdDtcbiAgdmFyIHdpbGRFZGdlID0gcmxvb2t1cChyLCBfXyk7XG4gIGlmIChpc19rZXlPcGVuKGtleSkpIHJldHVybiByd2lsZHNlcSh3aWxkRWRnZSk7XG4gIGlmIChpc19rZXlDbG9zZShrZXkpKSByZXR1cm4gKHdpbGRFZGdlIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpID8gd2lsZEVkZ2UudHJpZSA6IGVtcHR5VHJpZTtcbiAgcmV0dXJuIHdpbGRFZGdlO1xufVxuXG5mdW5jdGlvbiBpc19rZXlPcGVuKGspIHtcbiAgcmV0dXJuIGsgPT09IFNPQTtcbn1cblxuZnVuY3Rpb24gaXNfa2V5Q2xvc2Uoaykge1xuICByZXR1cm4gayA9PT0gRU9BO1xufVxuXG5mdW5jdGlvbiBpc19rZXlOb3JtYWwoaykge1xuICByZXR1cm4gIShpc19rZXlPcGVuKGspIHx8IGlzX2tleUNsb3NlKGspKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbnZhciB1bmlvblN1Y2Nlc3Nlc0RlZmF1bHQgPSBmdW5jdGlvbiAodjEsIHYyKSB7XG4gIGlmICh2MSA9PT0gdHJ1ZSkgcmV0dXJuIHYyO1xuICBpZiAodjIgPT09IHRydWUpIHJldHVybiB2MTtcbiAgcmV0dXJuIHYxLnVuaW9uKHYyKTtcbn07XG5cbnZhciBpbnRlcnNlY3RTdWNjZXNzZXNEZWZhdWx0ID0gZnVuY3Rpb24gKHYxLCB2Mikge1xuICByZXR1cm4gdjE7XG59O1xuXG52YXIgc3VidHJhY3RTdWNjZXNzZXNEZWZhdWx0ID0gZnVuY3Rpb24gKHYxLCB2Mikge1xuICB2YXIgciA9IHYxLnN1YnRyYWN0KHYyKTtcbiAgaWYgKHIuaXNFbXB0eSgpKSByZXR1cm4gbnVsbDtcbiAgcmV0dXJuIHI7XG59O1xuXG52YXIgbWF0Y2hUcmllU3VjY2Vzc2VzID0gZnVuY3Rpb24gKHYxLCB2MiwgYWNjKSB7XG4gIHJldHVybiBhY2MudW5pb24odjIpO1xufTtcblxudmFyIHByb2plY3RTdWNjZXNzID0gZnVuY3Rpb24gKHYpIHtcbiAgcmV0dXJuIHY7XG59O1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gZXhwYW5kV2lsZHNlcShyKSB7XG4gIHJldHVybiB1bmlvbihyd2lsZChyd2lsZHNlcShyKSksIHJzZXEoRU9BLCByKSk7XG59XG5cbmZ1bmN0aW9uIHVuaW9uKG8xLCBvMiwgdW5pb25TdWNjZXNzZXNPcHQpIHtcbiAgdmFyIHVuaW9uU3VjY2Vzc2VzID0gdW5pb25TdWNjZXNzZXNPcHQgfHwgdW5pb25TdWNjZXNzZXNEZWZhdWx0O1xuICByZXR1cm4gbWVyZ2UobzEsIG8yKTtcblxuICBmdW5jdGlvbiBtZXJnZShvMSwgbzIpIHtcbiAgICBpZiAoaXNfZW1wdHlUcmllKG8xKSkgcmV0dXJuIG8yO1xuICAgIGlmIChpc19lbXB0eVRyaWUobzIpKSByZXR1cm4gbzE7XG4gICAgcmV0dXJuIHdhbGsobzEsIG8yKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHdhbGsocjEsIHIyKSB7XG4gICAgaWYgKHIxIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcbiAgICAgIGlmIChyMiBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG5cdHJldHVybiByd2lsZHNlcSh3YWxrKHIxLnRyaWUsIHIyLnRyaWUpKTtcbiAgICAgIH1cbiAgICAgIHIxID0gZXhwYW5kV2lsZHNlcShyMS50cmllKTtcbiAgICB9IGVsc2UgaWYgKHIyIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcbiAgICAgIHIyID0gZXhwYW5kV2lsZHNlcShyMi50cmllKTtcbiAgICB9XG5cbiAgICBpZiAocjEgaW5zdGFuY2VvZiAkU3VjY2Vzcykge1xuICAgICAgaWYgKHIyIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcblx0cmV0dXJuIHJzdWNjZXNzKHVuaW9uU3VjY2Vzc2VzKHIxLnZhbHVlLCByMi52YWx1ZSkpO1xuICAgICAgfSBlbHNlIHtcblx0ZGllKFwiUm91dGUudW5pb246IGxlZnQgc2hvcnQhXCIpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocjIgaW5zdGFuY2VvZiAkU3VjY2Vzcykge1xuICAgICAgZGllKFwiUm91dGUudW5pb246IHJpZ2h0IHNob3J0IVwiKTtcbiAgICB9XG5cbiAgICB2YXIgdyA9IG1lcmdlKHJsb29rdXAocjEsIF9fKSwgcmxvb2t1cChyMiwgX18pKTtcbiAgICB2YXIgdGFyZ2V0O1xuXG4gICAgZnVuY3Rpb24gZXhhbWluZUtleShrZXkpIHtcbiAgICAgIGlmICgoa2V5ICE9PSBfXykgJiYgIXRhcmdldC5oYXMoa2V5KSkge1xuXHR0YXJnZXQgPSBydXBkYXRlKHRhcmdldCwga2V5LCBtZXJnZShybG9va3VwV2lsZChyMSwga2V5KSwgcmxvb2t1cFdpbGQocjIsIGtleSkpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNfZW1wdHlUcmllKHcpKSB7XG4gICAgICB2YXIgc21hbGxlciA9IHIxLnNpemUgPCByMi5zaXplID8gcjEgOiByMjtcbiAgICAgIHZhciBsYXJnZXIgID0gcjEuc2l6ZSA8IHIyLnNpemUgPyByMiA6IHIxO1xuICAgICAgdGFyZ2V0ID0gbGFyZ2VyO1xuICAgICAgc21hbGxlci5mb3JFYWNoKGZ1bmN0aW9uICh2YWwsIGtleSkge1xuXHR2YXIgayA9IG1lcmdlKHJsb29rdXAoc21hbGxlciwga2V5KSwgcmxvb2t1cChsYXJnZXIsIGtleSkpO1xuXHR0YXJnZXQgPSBydXBkYXRlKHRhcmdldCwga2V5LCBrKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0YXJnZXQgPSByd2lsZCh3KTtcbiAgICAgIHIxLmZvckVhY2goZnVuY3Rpb24gKHZhbCwga2V5KSB7IGV4YW1pbmVLZXkoa2V5KSB9KTtcbiAgICAgIHIyLmZvckVhY2goZnVuY3Rpb24gKHZhbCwga2V5KSB7IGV4YW1pbmVLZXkoa2V5KSB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9XG59XG5cbmZ1bmN0aW9uIHVuaW9uTigpIHtcbiAgdmFyIGFjYyA9IGVtcHR5VHJpZTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICBhY2MgPSB1bmlvbihhY2MsIGFyZ3VtZW50c1tpXSk7XG4gIH1cbiAgcmV0dXJuIGFjYztcbn1cblxuZnVuY3Rpb24gaW50ZXJzZWN0KG8xLCBvMiwgaW50ZXJzZWN0U3VjY2Vzc2VzT3B0LCBsZWZ0U2hvcnRPcHQpIHtcbiAgdmFyIGludGVyc2VjdFN1Y2Nlc3NlcyA9IGludGVyc2VjdFN1Y2Nlc3Nlc09wdCB8fCBpbnRlcnNlY3RTdWNjZXNzZXNEZWZhdWx0O1xuICB2YXIgbGVmdFNob3J0ID0gbGVmdFNob3J0T3B0IHx8IGZ1bmN0aW9uICh2LCByKSB7XG4gICAgZGllKFwiUm91dGUuaW50ZXJzZWN0OiBsZWZ0IHNpZGUgc2hvcnQhXCIpO1xuICB9O1xuICByZXR1cm4gd2FsayhvMSwgbzIpO1xuXG4gIGZ1bmN0aW9uIHdhbGtGbGlwcGVkKHIyLCByMSkgeyByZXR1cm4gd2FsayhyMSwgcjIpOyB9XG5cbiAgZnVuY3Rpb24gd2FsayhyMSwgcjIpIHtcbiAgICAvLyBJTlZBUklBTlQ6IHIxIGlzIGEgcGFydCBvZiB0aGUgb3JpZ2luYWwgbzEsIGFuZFxuICAgIC8vIGxpa2V3aXNlIGZvciByMi4gVGhpcyBpcyBzbyB0aGF0IHRoZSBmaXJzdCBhcmcgdG9cbiAgICAvLyBpbnRlcnNlY3RTdWNjZXNzZXMgYWx3YXlzIGNvbWVzIGZyb20gcjEsIGFuZCB0aGUgc2Vjb25kXG4gICAgLy8gZnJvbSByMi5cbiAgICBpZiAoaXNfZW1wdHlUcmllKHIxKSkgcmV0dXJuIGVtcHR5VHJpZTtcbiAgICBpZiAoaXNfZW1wdHlUcmllKHIyKSkgcmV0dXJuIGVtcHR5VHJpZTtcblxuICAgIGlmIChyMSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG4gICAgICBpZiAocjIgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHRyZXR1cm4gcndpbGRzZXEod2FsayhyMS50cmllLCByMi50cmllKSk7XG4gICAgICB9XG4gICAgICByMSA9IGV4cGFuZFdpbGRzZXEocjEudHJpZSk7XG4gICAgfSBlbHNlIGlmIChyMiBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG4gICAgICByMiA9IGV4cGFuZFdpbGRzZXEocjIudHJpZSk7XG4gICAgfVxuXG4gICAgaWYgKHIxIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcbiAgICAgIGlmIChyMiBpbnN0YW5jZW9mICRTdWNjZXNzKSB7XG5cdHJldHVybiByc3VjY2VzcyhpbnRlcnNlY3RTdWNjZXNzZXMocjEudmFsdWUsIHIyLnZhbHVlKSk7XG4gICAgICB9IGVsc2Uge1xuXHRyZXR1cm4gbGVmdFNob3J0KHIxLnZhbHVlLCByMik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHcxID0gcmxvb2t1cChyMSwgX18pO1xuICAgIHZhciB3MiA9IHJsb29rdXAocjIsIF9fKTtcbiAgICB2YXIgdyA9IHdhbGsodzEsIHcyKTtcblxuICAgIHZhciB0YXJnZXQgPSBlbXB0eVRyaWU7XG5cbiAgICBmdW5jdGlvbiBleGFtaW5lS2V5KGtleSkge1xuICAgICAgaWYgKChrZXkgIT09IF9fKSAmJiAhdGFyZ2V0LmhhcyhrZXkpKSB7XG5cdHRhcmdldCA9IHJ1cGRhdGUodGFyZ2V0LCBrZXksIHdhbGsocmxvb2t1cFdpbGQocjEsIGtleSksIHJsb29rdXBXaWxkKHIyLCBrZXkpKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzX2VtcHR5VHJpZSh3MSkpIHtcbiAgICAgIGlmIChpc19lbXB0eVRyaWUodzIpKSB7XG5cdChyMS5zaXplIDwgcjIuc2l6ZSA/IHIxIDogcjIpLmZvckVhY2goZnVuY3Rpb24gKHZhbCwga2V5KSB7IGV4YW1pbmVLZXkoa2V5KSB9KTtcbiAgICAgIH0gZWxzZSB7XG5cdHIxLmZvckVhY2goZnVuY3Rpb24gKHZhbCwga2V5KSB7IGV4YW1pbmVLZXkoa2V5KSB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGlzX2VtcHR5VHJpZSh3MikpIHtcblx0cjIuZm9yRWFjaChmdW5jdGlvbiAodmFsLCBrZXkpIHsgZXhhbWluZUtleShrZXkpIH0pO1xuICAgICAgfSBlbHNlIHtcblx0dGFyZ2V0ID0gcnVwZGF0ZSh0YXJnZXQsIF9fLCB3KTtcblx0cjEuZm9yRWFjaChmdW5jdGlvbiAodmFsLCBrZXkpIHsgZXhhbWluZUtleShrZXkpIH0pO1xuXHRyMi5mb3JFYWNoKGZ1bmN0aW9uICh2YWwsIGtleSkgeyBleGFtaW5lS2V5KGtleSkgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0YXJnZXQ7XG4gIH1cbn1cblxuLy8gVGhlIHN1YnRyYWN0U3VjY2Vzc2VzIGZ1bmN0aW9uIHNob3VsZCByZXR1cm4gbnVsbCB0byBzaWduYWwgXCJub1xuLy8gcmVtYWluaW5nIHN1Y2Nlc3MgdmFsdWVzXCIuXG5mdW5jdGlvbiBzdWJ0cmFjdChvMSwgbzIsIHN1YnRyYWN0U3VjY2Vzc2VzT3B0KSB7XG4gIHZhciBzdWJ0cmFjdFN1Y2Nlc3NlcyA9IHN1YnRyYWN0U3VjY2Vzc2VzT3B0IHx8IHN1YnRyYWN0U3VjY2Vzc2VzRGVmYXVsdDtcbiAgcmV0dXJuIHdhbGsobzEsIG8yKTtcblxuICBmdW5jdGlvbiB3YWxrRmxpcHBlZChyMiwgcjEpIHsgcmV0dXJuIHdhbGsocjEsIHIyKTsgfVxuXG4gIGZ1bmN0aW9uIHdhbGsocjEsIHIyKSB7XG4gICAgaWYgKGlzX2VtcHR5VHJpZShyMSkpIHtcbiAgICAgIHJldHVybiBlbXB0eVRyaWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChpc19lbXB0eVRyaWUocjIpKSB7XG5cdHJldHVybiByMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocjEgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuICAgICAgaWYgKHIyIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0cmV0dXJuIHJ3aWxkc2VxKHdhbGsocjEudHJpZSwgcjIudHJpZSkpO1xuICAgICAgfVxuICAgICAgcjEgPSBleHBhbmRXaWxkc2VxKHIxLnRyaWUpO1xuICAgIH0gZWxzZSBpZiAocjIgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuICAgICAgcjIgPSBleHBhbmRXaWxkc2VxKHIyLnRyaWUpO1xuICAgIH1cblxuICAgIGlmIChyMSBpbnN0YW5jZW9mICRTdWNjZXNzICYmIHIyIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcbiAgICAgIHJldHVybiByc3VjY2VzcyhzdWJ0cmFjdFN1Y2Nlc3NlcyhyMS52YWx1ZSwgcjIudmFsdWUpKTtcbiAgICB9XG5cbiAgICB2YXIgdzEgPSBybG9va3VwKHIxLCBfXyk7XG4gICAgdmFyIHcyID0gcmxvb2t1cChyMiwgX18pO1xuICAgIHZhciB3ID0gd2Fsayh3MSwgdzIpO1xuICAgIHZhciB0YXJnZXQ7XG5cbiAgICBmdW5jdGlvbiBleGFtaW5lS2V5KGtleSkge1xuICAgICAgaWYgKGtleSAhPT0gX18pIHtcblx0dmFyIGsxID0gcmxvb2t1cFdpbGQocjEsIGtleSk7XG5cdHZhciBrMiA9IHJsb29rdXBXaWxkKHIyLCBrZXkpO1xuXHR2YXIgdXBkYXRlZEsgPSB3YWxrKGsxLCBrMik7XG5cblx0Ly8gSGVyZSB3ZSBlbnN1cmUgYSBcIm1pbmltYWxcIiByZW1haW5kZXIgaW4gY2FzZXNcblx0Ly8gd2hlcmUgYWZ0ZXIgYW4gZXJhc3VyZSwgYSBwYXJ0aWN1bGFyIGtleSdzXG5cdC8vIGNvbnRpbnVhdGlvbiBpcyB0aGUgc2FtZSBhcyB0aGUgd2lsZGNhcmQnc1xuXHQvLyBjb250aW51YXRpb24uIFRPRE86IHRoZSBlcXVhbHMgY2hlY2sgbWF5XG5cdC8vIGJlIGV4cGVuc2l2ZS4gSWYgc28sIGhvdyBjYW4gaXQgYmUgbWFkZVxuXHQvLyBjaGVhcGVyP1xuXHRpZiAoaXNfa2V5T3BlbihrZXkpKSB7XG5cdCAgdGFyZ2V0ID0gcnVwZGF0ZSh0YXJnZXQsIGtleSxcblx0XHRcdCAgICgodXBkYXRlZEsgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkgJiZcblx0XHRcdCAgICBJbW11dGFibGUuaXModXBkYXRlZEsudHJpZSwgdykpXG5cdFx0XHQgICA/IHdcblx0XHRcdCAgIDogdXBkYXRlZEspO1xuXHR9IGVsc2Uge1xuXHQgIHRhcmdldCA9IHJ1cGRhdGUodGFyZ2V0LCBrZXksIHVwZGF0ZWRLKTtcblx0fVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpc19lbXB0eVRyaWUodzIpKSB7XG4gICAgICB0YXJnZXQgPSByMTtcbiAgICAgIHIyLmZvckVhY2goZnVuY3Rpb24gKHZhbCwga2V5KSB7IGV4YW1pbmVLZXkoa2V5KSB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGFyZ2V0ID0gZW1wdHlUcmllO1xuICAgICAgdGFyZ2V0ID0gcnVwZGF0ZSh0YXJnZXQsIF9fLCB3KTtcbiAgICAgIHIxLmZvckVhY2goZnVuY3Rpb24gKHZhbCwga2V5KSB7IGV4YW1pbmVLZXkoa2V5KSB9KTtcbiAgICAgIHIyLmZvckVhY2goZnVuY3Rpb24gKHZhbCwga2V5KSB7IGV4YW1pbmVLZXkoa2V5KSB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29sbGFwc2VXaWxkY2FyZFNlcXVlbmNlcyh0YXJnZXQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbGxhcHNlV2lsZGNhcmRTZXF1ZW5jZXModGFyZ2V0KSB7XG4gIC8vIEhlcmUsIHRoZSB0YXJnZXQgaXMgY29tcGxldGUuIElmIGl0IGhhcyBvbmx5IHR3byBrZXlzLFxuICAvLyBvbmUgd2lsZCBhbmQgb25lIGlzX2tleUNsb3NlLCBhbmQgd2lsZCdzIGNvbnRpbnVhdGlvblxuICAvLyBpcyBhICRXaWxkY2FyZFNlcXVlbmNlIGFuZCB0aGUgb3RoZXIgY29udGludWF0aW9uIGlzXG4gIC8vIGlkZW50aWNhbCB0byB0aGUgc2VxdWVuY2UncyBjb250aW51YXRpb24sIHRoZW4gcmVwbGFjZVxuICAvLyB0aGUgd2hvbGUgdGhpbmcgd2l0aCBhIG5lc3RlZCAkV2lsZGNhcmRTZXF1ZW5jZS5cbiAgLy8gKFdlIGtub3cgdyA9PT0gcmxvb2t1cCh0YXJnZXQsIF9fKSBmcm9tIGJlZm9yZS4pXG4gIC8vXG4gIC8vIFRPRE86IEkgc3VzcGVjdCBhY3R1YWxseSB0aGlzIGFwcGxpZXMgZXZlbiBpZiB0aGVyZSBhcmVcbiAgLy8gbW9yZSB0aGFuIHR3byBrZXlzLCBzbyBsb25nIGFzIGFsbCB0aGVpciBjb250aW51YXRpb25zXG4gIC8vIGFyZSBpZGVudGljYWwgYW5kIHRoZXJlJ3MgYXQgbGVhc3Qgb25lIGlzX2tleUNsb3NlXG4gIC8vIGFsb25nc2lkZSBhIHdpbGQuXG4gIGlmICh0YXJnZXQuc2l6ZSA9PT0gMikge1xuICAgIHZhciBmaW5hbFcgPSBybG9va3VwKHRhcmdldCwgX18pO1xuICAgIGlmIChmaW5hbFcgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuICAgICAgdGFyZ2V0LmZvckVhY2goZnVuY3Rpb24gKGssIGtleSkge1xuXHRpZiAoKGtleSAhPT0gX18pICYmIGlzX2tleUNsb3NlKGtleSkpIHtcblx0ICBpZiAoSW1tdXRhYmxlLmlzKGssIGZpbmFsVy50cmllKSkge1xuXHQgICAgdGFyZ2V0ID0gZmluYWxXO1xuXHQgICAgcmV0dXJuIGZhbHNlOyAvLyB0ZXJtaW5hdGUgdGhlIGl0ZXJhdGlvbiBlYXJseVxuXHQgIH1cblx0fVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB0YXJnZXQ7XG59XG5cbi8vIFJldHVybnMgbnVsbCBvbiBmYWlsZWQgbWF0Y2gsIG90aGVyd2lzZSB0aGUgYXBwcm9wcmlhdGUgc3VjY2Vzc1xuLy8gdmFsdWUgY29udGFpbmVkIGluIHRoZSB0cmllIHIuXG5mdW5jdGlvbiBtYXRjaFZhbHVlKHIsIHYpIHtcbiAgdmFyIGZhaWx1cmVSZXN1bHQgPSBudWxsO1xuXG4gIHZhciB2cyA9IEltbXV0YWJsZS5MaXN0Lm9mKHYpO1xuICB2YXIgc3RhY2sgPSBbSW1tdXRhYmxlLkxpc3QoKV07XG5cbiAgd2hpbGUgKCFpc19lbXB0eVRyaWUocikpIHtcbiAgICBpZiAociBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG4gICAgICBpZiAoc3RhY2subGVuZ3RoID09PSAwKSByZXR1cm4gZmFpbHVyZVJlc3VsdDtcbiAgICAgIHZzID0gc3RhY2sucG9wKCk7XG4gICAgICByID0gci50cmllO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHIgaW5zdGFuY2VvZiAkU3VjY2Vzcykge1xuICAgICAgaWYgKHZzLnNpemUgPT09IDAgJiYgc3RhY2subGVuZ3RoID09PSAwKSByZXR1cm4gci52YWx1ZTtcbiAgICAgIHJldHVybiBmYWlsdXJlUmVzdWx0O1xuICAgIH1cblxuICAgIGlmICh2cy5zaXplID09PSAwKSB7XG4gICAgICBpZiAoc3RhY2subGVuZ3RoID09PSAwKSByZXR1cm4gZmFpbHVyZVJlc3VsdDtcbiAgICAgIHZzID0gc3RhY2sucG9wKCk7XG4gICAgICByID0gcmxvb2t1cChyLCBFT0EpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdmFyIHYgPSB2cy5maXJzdCgpO1xuICAgIHZzID0gdnMuc2hpZnQoKTtcblxuICAgIGlmICh0eXBlb2YgdiA9PT0gJ3N0cmluZycgJiYgdi5zdWJzdHJpbmcoMCwgMikgPT09ICdfXycpIHtcbiAgICAgIGRpZShcIkNhbm5vdCBtYXRjaCBzcGVjaWFsIHN0cmluZyBzdGFydGluZyB3aXRoIF9fXCIpO1xuICAgIH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KHYpKSB7XG4gICAgICBpZiAoci5oYXMoU09BKSkge1xuXHRyID0gcmxvb2t1cChyLCBTT0EpO1xuXHRzdGFjay5wdXNoKHZzKTtcblx0dnMgPSBJbW11dGFibGUuTGlzdCh2KTtcbiAgICAgIH0gZWxzZSB7XG5cdHIgPSBybG9va3VwKHIsIF9fKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzU3RydWN0dXJlKHYpKSB7XG4gICAgICBpZiAoci5oYXMoU09BKSkge1xuICAgICAgICByID0gcmxvb2t1cChyLCBTT0EpO1xuICAgICAgICBzdGFjay5wdXNoKHZzKTtcbiAgICAgICAgdnMgPSBJbW11dGFibGUuTGlzdC5vZih2LiRTeW5kaWNhdGVNZXRhJC5sYWJlbCk7XG4gICAgICAgIHZhciBhcmdzID0gdi4kU3luZGljYXRlTWV0YSQuYXJndW1lbnRzO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICB2cyA9IHZzLnB1c2godlthcmdzW2ldXSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHIgPSBybG9va3VwKHIsIF9fKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHIuaGFzKHYpKSB7XG5cdHIgPSBybG9va3VwKHIsIHYpO1xuICAgICAgfSBlbHNlIHtcblx0ciA9IHJsb29rdXAociwgX18pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWlsdXJlUmVzdWx0O1xufVxuXG5mdW5jdGlvbiBtYXRjaFRyaWUobzEsIG8yLCBzZWVkLCBsZWZ0U2hvcnRPcHQpIHtcbiAgdmFyIGFjYyA9IHR5cGVvZiBzZWVkID09PSAndW5kZWZpbmVkJyA/IEltbXV0YWJsZS5TZXQoKSA6IHNlZWQ7IC8vIHZhcmlhYmxlIHVwZGF0ZWQgaW1wZXJhdGl2ZWx5XG4gIHZhciBsZWZ0U2hvcnQgPSBsZWZ0U2hvcnRPcHQgfHwgZnVuY3Rpb24gKHYsIHIsIGFjYykge1xuICAgIGRpZShcIlJvdXRlLm1hdGNoVHJpZTogbGVmdCBzaWRlIHNob3J0IVwiKTtcbiAgfTtcbiAgd2FsayhvMSwgbzIpO1xuICByZXR1cm4gYWNjO1xuXG4gIGZ1bmN0aW9uIHdhbGtGbGlwcGVkKHIyLCByMSkgeyByZXR1cm4gd2FsayhyMSwgcjIpOyB9XG5cbiAgZnVuY3Rpb24gd2FsayhyMSwgcjIpIHtcbiAgICBpZiAoaXNfZW1wdHlUcmllKHIxKSB8fCBpc19lbXB0eVRyaWUocjIpKSByZXR1cm47XG5cbiAgICBpZiAocjEgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuICAgICAgaWYgKHIyIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0d2FsayhyMS50cmllLCByMi50cmllKTtcblx0cmV0dXJuO1xuICAgICAgfVxuICAgICAgcjEgPSBleHBhbmRXaWxkc2VxKHIxLnRyaWUpO1xuICAgIH0gZWxzZSBpZiAocjIgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuICAgICAgcjIgPSBleHBhbmRXaWxkc2VxKHIyLnRyaWUpO1xuICAgIH1cblxuICAgIGlmIChyMSBpbnN0YW5jZW9mICRTdWNjZXNzKSB7XG4gICAgICBpZiAocjIgaW5zdGFuY2VvZiAkU3VjY2Vzcykge1xuXHRhY2MgPSBtYXRjaFRyaWVTdWNjZXNzZXMocjEudmFsdWUsIHIyLnZhbHVlLCBhY2MpO1xuICAgICAgfSBlbHNlIHtcblx0YWNjID0gbGVmdFNob3J0KHIxLnZhbHVlLCByMiwgYWNjKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKHIyIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcbiAgICAgIGRpZShcIlJvdXRlLm1hdGNoVHJpZTogcmlnaHQgc2lkZSBzaG9ydCFcIik7XG4gICAgfVxuXG4gICAgdmFyIHcxID0gcmxvb2t1cChyMSwgX18pO1xuICAgIHZhciB3MiA9IHJsb29rdXAocjIsIF9fKTtcbiAgICB3YWxrKHcxLCB3Mik7XG5cbiAgICBmdW5jdGlvbiBleGFtaW5lS2V5KGtleSkge1xuICAgICAgaWYgKGtleSAhPT0gX18pIHtcblx0dmFyIGsxID0gcmxvb2t1cChyMSwga2V5KTtcblx0dmFyIGsyID0gcmxvb2t1cChyMiwga2V5KTtcblx0aWYgKGlzX2VtcHR5VHJpZShrMSkpIHtcblx0ICBpZiAoaXNfZW1wdHlUcmllKGsyKSkge1xuXHQgICAgcmV0dXJuO1xuXHQgIH0gZWxzZSB7XG5cdCAgICB3YWxrV2lsZCh3YWxrLCB3MSwga2V5LCBrMik7XG5cdCAgfVxuXHR9IGVsc2Uge1xuXHQgIGlmIChpc19lbXB0eVRyaWUoazIpKSB7XG5cdCAgICB3YWxrV2lsZCh3YWxrRmxpcHBlZCwgdzIsIGtleSwgazEpO1xuXHQgIH0gZWxzZSB7XG5cdCAgICB3YWxrKGsxLCBrMik7XG5cdCAgfVxuXHR9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gT3B0aW1pemUgc2ltaWxhcmx5IHRvIGludGVyc2VjdCgpLlxuICAgIGlmIChpc19lbXB0eVRyaWUodzEpKSB7XG4gICAgICBpZiAoaXNfZW1wdHlUcmllKHcyKSkge1xuXHQocjEuc2l6ZSA8IHIyLnNpemUgPyByMSA6IHIyKS5mb3JFYWNoKGZ1bmN0aW9uICh2YWwsIGtleSkgeyBleGFtaW5lS2V5KGtleSkgfSk7XG4gICAgICB9IGVsc2Uge1xuXHRyMS5mb3JFYWNoKGZ1bmN0aW9uICh2YWwsIGtleSkgeyBleGFtaW5lS2V5KGtleSkgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChpc19lbXB0eVRyaWUodzIpKSB7XG5cdHIyLmZvckVhY2goZnVuY3Rpb24gKHZhbCwga2V5KSB7IGV4YW1pbmVLZXkoa2V5KSB9KTtcbiAgICAgIH0gZWxzZSB7XG5cdHIxLmZvckVhY2goZnVuY3Rpb24gKHZhbCwga2V5KSB7IGV4YW1pbmVLZXkoa2V5KSB9KTtcblx0cjIuZm9yRWFjaChmdW5jdGlvbiAodmFsLCBrZXkpIHsgZXhhbWluZUtleShrZXkpIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHdhbGtXaWxkKHdhbGtlciwgdywga2V5LCBrKSB7XG4gICAgaWYgKGlzX2VtcHR5VHJpZSh3KSkgcmV0dXJuO1xuICAgIGlmIChpc19rZXlPcGVuKGtleSkpIHtcbiAgICAgIHdhbGtlcihyd2lsZHNlcSh3KSwgayk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChpc19rZXlDbG9zZShrZXkpKSB7XG4gICAgICBpZiAodyBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB3YWxrZXIody50cmllLCBrKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgd2Fsa2VyKHcsIGspO1xuICB9XG59XG5cbmZ1bmN0aW9uIGFwcGVuZFRyaWUobSwgbVRhaWxGbikge1xuICByZXR1cm4gd2FsayhtKTtcblxuICBmdW5jdGlvbiB3YWxrKG0pIHtcbiAgICBpZiAoaXNfZW1wdHlUcmllKG0pKSByZXR1cm4gZW1wdHlUcmllO1xuICAgIGlmIChtIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHJldHVybiByd2lsZHNlcSh3YWxrKG0udHJpZSkpO1xuICAgIGlmIChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIGRpZShcIklsbC1mb3JtZWQgdHJpZVwiKTtcblxuICAgIHZhciB0YXJnZXQgPSBlbXB0eVRyaWU7XG4gICAgbS5mb3JFYWNoKGZ1bmN0aW9uIChrLCBrZXkpIHtcbiAgICAgIGlmIChpc19rZXlDbG9zZShrZXkpICYmIChrIGluc3RhbmNlb2YgJFN1Y2Nlc3MpKSB7XG5cdHRhcmdldCA9IHVuaW9uKHRhcmdldCwgbVRhaWxGbihrLnZhbHVlKSk7XG4gICAgICB9IGVsc2Uge1xuXHR0YXJnZXQgPSBydXBkYXRlKHRhcmdldCwga2V5LCB3YWxrKGspKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9XG59XG5cbmZ1bmN0aW9uIHRyaWVQcnVuZUJyYW5jaChtLCBrZXlzKSB7XG4gIGlmIChrZXlzLmlzRW1wdHkoKSkgcmV0dXJuIGVtcHR5VHJpZTtcblxuICBpZiAoaXNfZW1wdHlUcmllKG0pKSByZXR1cm4gZW1wdHlUcmllO1xuICBpZiAobSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG4gICAgcmV0dXJuIGNvbGxhcHNlV2lsZGNhcmRTZXF1ZW5jZXModHJpZVBydW5lQnJhbmNoKGV4cGFuZFdpbGRzZXEobS50cmllKSwga2V5cykpO1xuICB9XG4gIGlmIChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHJldHVybiBtO1xuXG4gIHZhciBrZXkgPSBrZXlzLmZpcnN0KCk7XG4gIHZhciByZXN0ID0ga2V5cy5zaGlmdCgpO1xuICByZXR1cm4gcnVwZGF0ZShtLCBrZXksIHRyaWVQcnVuZUJyYW5jaChybG9va3VwV2lsZChtLCBrZXkpLCByZXN0KSk7XG59XG5cbmZ1bmN0aW9uIHRyaWVTdGVwKG0sIGtleSkge1xuICBpZiAoaXNfZW1wdHlUcmllKG0pKSByZXR1cm4gZW1wdHlUcmllO1xuICBpZiAobSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSByZXR1cm4gKGlzX2tleUNsb3NlKGtleSkgPyBtLnRyaWUgOiBtKTtcbiAgaWYgKG0gaW5zdGFuY2VvZiAkU3VjY2VzcykgcmV0dXJuIGVtcHR5VHJpZTtcbiAgcmV0dXJuIHJsb29rdXBXaWxkKG0sIGtleSk7XG59XG5cbmZ1bmN0aW9uIHJlbGFiZWwobSwgZikge1xuICByZXR1cm4gd2FsayhtKTtcblxuICBmdW5jdGlvbiB3YWxrKG0pIHtcbiAgICBpZiAoaXNfZW1wdHlUcmllKG0pKSByZXR1cm4gZW1wdHlUcmllO1xuICAgIGlmIChtIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHJldHVybiByd2lsZHNlcSh3YWxrKG0udHJpZSkpO1xuICAgIGlmIChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHJldHVybiByc3VjY2VzcyhmKG0udmFsdWUpKTtcblxuICAgIHZhciB0YXJnZXQgPSBlbXB0eVRyaWU7XG4gICAgbS5mb3JFYWNoKGZ1bmN0aW9uIChrLCBrZXkpIHtcbiAgICAgIHRhcmdldCA9IHJ1cGRhdGUodGFyZ2V0LCBrZXksIHdhbGsoaykpO1xuICAgIH0pO1xuICAgIHJldHVybiB0YXJnZXQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tcGlsZVByb2plY3Rpb24oLyogcHJvamVjdGlvbiwgcHJvamVjdGlvbiwgLi4uICovKSB7XG4gIHZhciBuYW1lcyA9IFtdO1xuICB2YXIgYWNjID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgd2Fsayhhcmd1bWVudHNbaV0pO1xuICB9XG4gIGFjYy5wdXNoKEVPQSk7XG4gIHJldHVybiB7bmFtZXM6IG5hbWVzLCBzcGVjOiBhY2N9O1xuXG4gIGZ1bmN0aW9uIHdhbGsocCkge1xuICAgIGlmIChpc0NhcHR1cmUocCkpIHtcbiAgICAgIG5hbWVzLnB1c2goY2FwdHVyZU5hbWUocCkpO1xuICAgICAgYWNjLnB1c2goU09DKTtcbiAgICAgIHdhbGsoY2FwdHVyZVBhdHRlcm4ocCkpO1xuICAgICAgYWNjLnB1c2goRU9DKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShwKSkge1xuICAgICAgYWNjLnB1c2goU09BKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuXHR3YWxrKHBbaV0pO1xuICAgICAgfVxuICAgICAgYWNjLnB1c2goRU9BKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoaXNTdHJ1Y3R1cmUocCkpIHtcbiAgICAgIGFjYy5wdXNoKFNPQSk7XG4gICAgICBhY2MucHVzaChwLiRTeW5kaWNhdGVNZXRhJC5sYWJlbCk7XG4gICAgICB2YXIgYXJncyA9IHAuJFN5bmRpY2F0ZU1ldGEkLmFyZ3VtZW50cztcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuICAgICAgICB3YWxrKHBbYXJnc1tpXV0pO1xuICAgICAgfVxuICAgICAgYWNjLnB1c2goRU9BKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocCBpbnN0YW5jZW9mICRFbWJlZGRlZCkge1xuICAgICAgZGllKFwiQ2Fubm90IGVtYmVkIHRyaWUgaW4gcHJvamVjdGlvblwiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWNjLnB1c2gocCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHByb2plY3Rpb25Ub1BhdHRlcm4ocCkge1xuICByZXR1cm4gd2FsayhwKTtcblxuICBmdW5jdGlvbiB3YWxrKHApIHtcbiAgICBpZiAoaXNDYXB0dXJlKHApKSByZXR1cm4gd2FsayhjYXB0dXJlUGF0dGVybihwKSk7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShwKSkge1xuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XG5cdHJlc3VsdC5wdXNoKHdhbGsocFtpXSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBpZiAoaXNTdHJ1Y3R1cmUocCkpIHtcbiAgICAgIHZhciByZXN1bHQgPSB7XCIkU3luZGljYXRlTWV0YSRcIjogcC4kU3luZGljYXRlTWV0YSR9O1xuICAgICAgdmFyIGFyZ3MgPSBwLiRTeW5kaWNhdGVNZXRhJC5hcmd1bWVudHM7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcmVzdWx0W2FyZ3NbaV1dID0gd2FsayhwW2FyZ3NbaV1dKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgaWYgKHAgaW5zdGFuY2VvZiAkRW1iZWRkZWQpIHtcbiAgICAgIHJldHVybiBwLnRyaWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBwO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9qZWN0KG0sIGNvbXBpbGVkUHJvamVjdGlvbikge1xuICB2YXIgc3BlYyA9IGNvbXBpbGVkUHJvamVjdGlvbi5zcGVjO1xuICByZXR1cm4gd2FsayhmYWxzZSwgbSwgMCk7XG5cbiAgZnVuY3Rpb24gd2Fsayhpc0NhcHR1cmluZywgbSwgc3BlY0luZGV4KSB7XG4gICAgaWYgKHNwZWNJbmRleCA+PSBzcGVjLmxlbmd0aCkge1xuICAgICAgaWYgKGlzQ2FwdHVyaW5nKSBkaWUoXCJCYWQgc3BlY2lmaWNhdGlvbjogdW5jbG9zZWQgY2FwdHVyZVwiKTtcbiAgICAgIGlmIChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcblx0cmV0dXJuIHJzZXEoRU9BLCByc3VjY2Vzcyhwcm9qZWN0U3VjY2VzcyhtLnZhbHVlKSkpO1xuICAgICAgfSBlbHNlIHtcblx0cmV0dXJuIGVtcHR5VHJpZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNfZW1wdHlUcmllKG0pKSByZXR1cm4gZW1wdHlUcmllO1xuXG4gICAgdmFyIGl0ZW0gPSBzcGVjW3NwZWNJbmRleF07XG4gICAgdmFyIG5leHRJbmRleCA9IHNwZWNJbmRleCArIDE7XG5cbiAgICBpZiAoaXRlbSA9PT0gRU9DKSB7XG4gICAgICBpZiAoIWlzQ2FwdHVyaW5nKSBkaWUoXCJCYWQgc3BlY2lmaWNhdGlvbjogdW5leHBlY3RlZCBFT0NcIik7XG4gICAgICByZXR1cm4gd2FsayhmYWxzZSwgbSwgbmV4dEluZGV4KTtcbiAgICB9XG5cbiAgICBpZiAoaXRlbSA9PT0gU09DKSB7XG4gICAgICBpZiAoaXNDYXB0dXJpbmcpIGRpZShcIkJhZCBzcGVjaWZpY2F0aW9uOiBuZXN0ZWQgY2FwdHVyZVwiKTtcbiAgICAgIHJldHVybiB3YWxrKHRydWUsIG0sIG5leHRJbmRleCk7XG4gICAgfVxuXG4gICAgaWYgKGl0ZW0gPT09IF9fKSB7XG4gICAgICBpZiAobSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG5cdGlmIChpc0NhcHR1cmluZykge1xuXHQgIHJldHVybiByd2lsZCh3YWxrKGlzQ2FwdHVyaW5nLCBtLCBuZXh0SW5kZXgpKTtcblx0fSBlbHNlIHtcblx0ICByZXR1cm4gd2Fsayhpc0NhcHR1cmluZywgbSwgbmV4dEluZGV4KTtcblx0fVxuICAgICAgfVxuXG4gICAgICBpZiAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSB7XG5cdHJldHVybiBlbXB0eVRyaWU7XG4gICAgICB9XG5cbiAgICAgIHZhciB0YXJnZXQ7XG4gICAgICBpZiAoaXNDYXB0dXJpbmcpIHtcblx0dGFyZ2V0ID0gZW1wdHlUcmllO1xuXHR0YXJnZXQgPSBydXBkYXRlKHRhcmdldCwgX18sIHdhbGsoaXNDYXB0dXJpbmcsIHJsb29rdXAobSwgX18pLCBuZXh0SW5kZXgpKTtcblx0bS5mb3JFYWNoKGZ1bmN0aW9uIChtaywga2V5KSB7XG5cdCAgaWYgKGtleSAhPT0gX18pIHtcblx0ICAgIGlmIChpc19rZXlPcGVuKGtleSkpIHtcblx0ICAgICAgdGFyZ2V0ID0gcnVwZGF0ZSh0YXJnZXQsIGtleSwgY2FwdHVyZU5lc3RlZChtaywgZnVuY3Rpb24gKG1rMikge1xuXHRcdHJldHVybiB3YWxrKGlzQ2FwdHVyaW5nLCBtazIsIG5leHRJbmRleCk7XG5cdCAgICAgIH0pKTtcblx0ICAgIH0gZWxzZSBpZiAoaXNfa2V5Q2xvc2Uoa2V5KSkge1xuXHQgICAgICAvLyBkbyBub3RoaW5nXG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICB0YXJnZXQgPSBydXBkYXRlKHRhcmdldCwga2V5LCB3YWxrKGlzQ2FwdHVyaW5nLCBtaywgbmV4dEluZGV4KSk7XG5cdCAgICB9XG5cdCAgfVxuXHR9KTtcbiAgICAgIH0gZWxzZSB7XG5cdHRhcmdldCA9IHdhbGsoaXNDYXB0dXJpbmcsIHJsb29rdXAobSwgX18pLCBuZXh0SW5kZXgpO1xuXHRtLmZvckVhY2goZnVuY3Rpb24gKG1rLCBrZXkpIHtcblx0ICBpZiAoa2V5ICE9PSBfXykge1xuXHQgICAgaWYgKGlzX2tleU9wZW4oa2V5KSkge1xuXHQgICAgICB0YXJnZXQgPSB1bmlvbih0YXJnZXQsIHNraXBOZXN0ZWQobWssIGZ1bmN0aW9uIChtazIpIHtcblx0XHRyZXR1cm4gd2Fsayhpc0NhcHR1cmluZywgbWsyLCBuZXh0SW5kZXgpO1xuXHQgICAgICB9KSk7XG5cdCAgICB9IGVsc2UgaWYgKGlzX2tleUNsb3NlKGtleSkpIHtcblx0ICAgICAgLy8gZG8gbm90aGluZ1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgdGFyZ2V0ID0gdW5pb24odGFyZ2V0LCB3YWxrKGlzQ2FwdHVyaW5nLCBtaywgbmV4dEluZGV4KSk7XG5cdCAgICB9XG5cdCAgfVxuXHR9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuXG4gICAgdmFyIHJlc3VsdDtcbiAgICBpZiAobSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG4gICAgICBpZiAoaXNfa2V5T3BlbihpdGVtKSkge1xuXHRyZXN1bHQgPSB3YWxrKGlzQ2FwdHVyaW5nLCByd2lsZHNlcShtKSwgbmV4dEluZGV4KTtcbiAgICAgIH0gZWxzZSBpZiAoaXNfa2V5Q2xvc2UoaXRlbSkpIHtcblx0cmVzdWx0ID0gd2Fsayhpc0NhcHR1cmluZywgbS50cmllLCBuZXh0SW5kZXgpO1xuICAgICAgfSBlbHNlIHtcblx0cmVzdWx0ID0gd2Fsayhpc0NhcHR1cmluZywgbSwgbmV4dEluZGV4KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG0gaW5zdGFuY2VvZiAkU3VjY2Vzcykge1xuICAgICAgcmVzdWx0ID0gZW1wdHlUcmllO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaXNfa2V5T3BlbihpdGVtKSkge1xuXHRyZXN1bHQgPSB3YWxrKGlzQ2FwdHVyaW5nLCByd2lsZHNlcShybG9va3VwKG0sIF9fKSksIG5leHRJbmRleCk7XG4gICAgICB9IGVsc2UgaWYgKGlzX2tleUNsb3NlKGl0ZW0pKSB7XG5cdHJlc3VsdCA9IGVtcHR5VHJpZTtcbiAgICAgIH0gZWxzZSB7XG5cdHJlc3VsdCA9IHdhbGsoaXNDYXB0dXJpbmcsIHJsb29rdXAobSwgX18pLCBuZXh0SW5kZXgpO1xuICAgICAgfVxuICAgICAgcmVzdWx0ID0gdW5pb24ocmVzdWx0LCB3YWxrKGlzQ2FwdHVyaW5nLCBybG9va3VwKG0sIGl0ZW0pLCBuZXh0SW5kZXgpKTtcbiAgICB9XG4gICAgaWYgKGlzQ2FwdHVyaW5nKSB7XG4gICAgICByZXN1bHQgPSByc2VxKGl0ZW0sIHJlc3VsdCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiBjYXB0dXJlTmVzdGVkKG0sIGNvbnQpIHtcbiAgICBpZiAobSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG4gICAgICByZXR1cm4gcndpbGRzZXEoY29udChtLnRyaWUpKTtcbiAgICB9XG5cbiAgICBpZiAoaXNfZW1wdHlUcmllKG0pIHx8IChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpKSB7XG4gICAgICByZXR1cm4gZW1wdHlUcmllO1xuICAgIH1cblxuICAgIHZhciB0YXJnZXQgPSBlbXB0eVRyaWU7XG4gICAgdGFyZ2V0ID0gcnVwZGF0ZSh0YXJnZXQsIF9fLCBjYXB0dXJlTmVzdGVkKHJsb29rdXAobSwgX18pLCBjb250KSk7XG4gICAgbS5mb3JFYWNoKGZ1bmN0aW9uIChtaywga2V5KSB7XG4gICAgICBpZiAoa2V5ICE9PSBfXykge1xuXHRpZiAoaXNfa2V5T3BlbihrZXkpKSB7XG5cdCAgdGFyZ2V0ID0gcnVwZGF0ZSh0YXJnZXQsIGtleSwgY2FwdHVyZU5lc3RlZChtaywgZnVuY3Rpb24gKG1rMikge1xuXHQgICAgcmV0dXJuIGNhcHR1cmVOZXN0ZWQobWsyLCBjb250KTtcblx0ICB9KSk7XG5cdH0gZWxzZSBpZiAoaXNfa2V5Q2xvc2Uoa2V5KSkge1xuXHQgIHRhcmdldCA9IHJ1cGRhdGUodGFyZ2V0LCBrZXksIGNvbnQobWspKTtcblx0fSBlbHNlIHtcblx0ICB0YXJnZXQgPSBydXBkYXRlKHRhcmdldCwga2V5LCBjYXB0dXJlTmVzdGVkKG1rLCBjb250KSk7XG5cdH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9XG5cbiAgZnVuY3Rpb24gc2tpcE5lc3RlZChtLCBjb250KSB7XG4gICAgaWYgKG0gaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuICAgICAgcmV0dXJuIGNvbnQobS50cmllKTtcbiAgICB9XG5cbiAgICBpZiAoaXNfZW1wdHlUcmllKG0pIHx8IChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpKSB7XG4gICAgICByZXR1cm4gZW1wdHlUcmllO1xuICAgIH1cblxuICAgIHZhciB0YXJnZXQgPSBza2lwTmVzdGVkKHJsb29rdXAobSwgX18pLCBjb250KTtcbiAgICBtLmZvckVhY2goZnVuY3Rpb24gKG1rLCBrZXkpIHtcbiAgICAgIGlmIChrZXkgIT09IF9fKSB7XG5cdGlmIChpc19rZXlPcGVuKGtleSkpIHtcblx0ICB0YXJnZXQgPSB1bmlvbih0YXJnZXQsIHNraXBOZXN0ZWQobWssIGZ1bmN0aW9uIChtazIpIHtcblx0ICAgIHJldHVybiBza2lwTmVzdGVkKG1rMiwgY29udClcblx0ICB9KSk7XG5cdH0gZWxzZSBpZiAoaXNfa2V5Q2xvc2Uoa2V5KSkge1xuXHQgIHRhcmdldCA9IHVuaW9uKHRhcmdldCwgY29udChtaykpO1xuXHR9IGVsc2Uge1xuXHQgIHRhcmdldCA9IHVuaW9uKHRhcmdldCwgc2tpcE5lc3RlZChtaywgY29udCkpO1xuXHR9XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfVxufVxuXG5mdW5jdGlvbiB0cmllS2V5cyhtKSB7XG4gIGlmIChpc19lbXB0eVRyaWUobSkpIHJldHVybiBJbW11dGFibGUuU2V0KCk7XG4gIHZhciByZXN1bHQgPSB3YWxrU2VxKG0sIGZ1bmN0aW9uICh2c3MsIHZzaykgeyByZXR1cm4gdnNzOyB9KTtcbiAgaWYgKHJlc3VsdCA9PT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gIHJldHVybiBJbW11dGFibGUuU2V0KHJlc3VsdCk7XG5cbiAgZnVuY3Rpb24gd2FsayhtLCBrKSB7XG4gICAgaWYgKG0gaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkgcmV0dXJuIG51bGw7XG4gICAgaWYgKG0gaW5zdGFuY2VvZiAkU3VjY2VzcykgcmV0dXJuIFtdO1xuICAgIGlmIChtLmhhcyhfXykpIHJldHVybiBudWxsO1xuICAgIHZhciBhY2MgPSBbXTtcbiAgICBtLmZvckVhY2goZnVuY3Rpb24gKG1rLCBrZXkpIHtcbiAgICAgIHZhciBwaWVjZTtcbiAgICAgIGlmIChpc19rZXlPcGVuKGtleSkpIHtcblx0cGllY2UgPSB3YWxrU2VxKG1rLCBmdW5jdGlvbiAodnNzLCB2c2spIHtcblx0ICB2YXIgYWNjID0gW107XG5cdCAgZm9yICh2YXIgaSA9IDA7IGkgPCB2c3MubGVuZ3RoOyBpKyspIHtcblx0ICAgIHZhciB2cyA9IHZzc1tpXTtcblx0ICAgIGFjYyA9IGFjYy5jb25jYXQoayh0cmFuc2Zvcm1TZXFzKHZzLCBrZXkpLCB2c2spKTtcblx0ICB9XG5cdCAgcmV0dXJuIGFjYztcblx0fSk7XG4gICAgICB9IGVsc2UgaWYgKGlzX2tleUNsb3NlKGtleSkpIHtcblx0ZGllKFwidHJpZUtleXM6IGludGVybmFsIGVycm9yOiB1bmV4cGVjdGVkIGtleS1jbG9zZVwiKTtcbiAgICAgIH0gZWxzZSB7XG5cdHBpZWNlID0gayhrZXksIG1rKTtcbiAgICAgIH1cbiAgICAgIGlmIChwaWVjZSA9PT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gICAgICBhY2MgPSBhY2MuY29uY2F0KHBpZWNlKTtcbiAgICB9KTtcbiAgICByZXR1cm4gYWNjO1xuICB9XG5cbiAgZnVuY3Rpb24gd2Fsa1NlcShtLCBrKSB7XG4gICAgaWYgKG0gaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkgcmV0dXJuIG51bGw7XG4gICAgaWYgKG0gaW5zdGFuY2VvZiAkU3VjY2VzcykgcmV0dXJuIGsoW10sIGVtcHR5VHJpZSk7IC8vIFRPRE86ID8/XG4gICAgaWYgKG0uaGFzKF9fKSkgcmV0dXJuIG51bGw7XG4gICAgdmFyIGFjYyA9IFtdO1xuICAgIG0uZm9yRWFjaChmdW5jdGlvbiAobWssIGtleSkge1xuICAgICAgdmFyIHBpZWNlO1xuICAgICAgaWYgKGlzX2tleUNsb3NlKGtleSkpIHtcblx0cGllY2UgPSBrKFtJbW11dGFibGUuTGlzdCgpXSwgbWspO1xuICAgICAgfSBlbHNlIHtcblx0cGllY2UgPSB3YWxrKHJzZXEoa2V5LCBtayksIGZ1bmN0aW9uICh2LCB2aykge1xuXHQgIHJldHVybiB3YWxrU2VxKHZrLCBmdW5jdGlvbiAodnNzLCB2c2spIHtcblx0ICAgIHZhciBhY2MgPSBbXTtcblx0ICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdnNzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgIGFjYy5wdXNoKHZzc1tpXS51bnNoaWZ0KHYpKTtcblx0ICAgIH1cblx0ICAgIHJldHVybiBrKGFjYywgdnNrKTtcblx0ICB9KTtcblx0fSk7XG4gICAgICB9XG4gICAgICBpZiAocGllY2UgPT09IG51bGwpIHJldHVybiBudWxsO1xuICAgICAgYWNjID0gYWNjLmNvbmNhdChwaWVjZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjYztcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYW5zZm9ybVNlcXModnMsIG9wZW5lcikge1xuICAgIGlmIChvcGVuZXIgPT09IFNPQSkgcmV0dXJuIHZzO1xuICAgIGRpZShcIkludGVybmFsIGVycm9yOiB1bmtub3duIG9wZW5lciBcIiArIG9wZW5lcik7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2FwdHVyZVRvT2JqZWN0KGNhcHR1cmVzLCBjb21waWxlZFByb2plY3Rpb24pIHtcbiAgdmFyIGQgPSB7fTtcbiAgY2FwdHVyZXMuZm9yRWFjaChmdW5jdGlvbiAoa2V5LCBpbmRleCkge1xuICAgIGRbY29tcGlsZWRQcm9qZWN0aW9uLm5hbWVzW2luZGV4XSB8fCAoJyQnICsgaW5kZXgpXSA9IGtleTtcbiAgfSk7XG4gIHJldHVybiBkO1xufVxuXG5mdW5jdGlvbiB0cmllS2V5c1RvT2JqZWN0cyh0cmllS2V5c1Jlc3VsdCwgY29tcGlsZWRQcm9qZWN0aW9uKSB7XG4gIGlmICh0cmllS2V5c1Jlc3VsdCA9PT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gIHJldHVybiB0cmllS2V5c1Jlc3VsdC50b0xpc3QoKS5tYXAoZnVuY3Rpb24gKGUpIHsgcmV0dXJuIGNhcHR1cmVUb09iamVjdChlLCBjb21waWxlZFByb2plY3Rpb24pOyB9KTtcbn1cblxuZnVuY3Rpb24gcHJvamVjdE9iamVjdHMobSwgY29tcGlsZWRQcm9qZWN0aW9uKSB7XG4gIHJldHVybiB0cmllS2V5c1RvT2JqZWN0cyh0cmllS2V5cyhwcm9qZWN0KG0sIGNvbXBpbGVkUHJvamVjdGlvbikpLCBjb21waWxlZFByb2plY3Rpb24pO1xufVxuXG5mdW5jdGlvbiBwcmV0dHlUcmllKG0sIGluaXRpYWxJbmRlbnQpIHtcbiAgdmFyIGFjYyA9IFtdO1xuICB3YWxrKGluaXRpYWxJbmRlbnQgfHwgMCwgbSk7XG4gIHJldHVybiBhY2Muam9pbignJyk7XG5cbiAgZnVuY3Rpb24gd2FsayhpLCBtKSB7XG4gICAgaWYgKG0gaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuICAgICAgYWNjLnB1c2goXCIuLi4+XCIpO1xuICAgICAgd2FsayhpICsgNCwgbS50cmllKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKG0gaW5zdGFuY2VvZiAkU3VjY2Vzcykge1xuICAgICAgdmFyIHYgPSBtLnZhbHVlO1xuICAgICAgaWYgKEltbXV0YWJsZS5TZXQuaXNTZXQodikpIHsgdiA9IHYudG9BcnJheSgpOyB9XG4gICAgICBhY2MucHVzaChcIntcIiArIEpTT04uc3RyaW5naWZ5KHYpICsgXCJ9XCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChtLnNpemUgPT09IDApIHtcbiAgICAgIGFjYy5wdXNoKFwiOjo6IG5vdGhpbmdcIik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIG5lZWRTZXAgPSBmYWxzZTtcbiAgICBtLnRvT3JkZXJlZE1hcCgpXG4gICAgICAuc29ydEJ5KGZ1bmN0aW9uIChrLCBrZXkpIHsgcmV0dXJuIGtleSB9KVxuICAgICAgLmZvckVhY2goZnVuY3Rpb24gKGssIGtleSkge1xuXHRpZiAobmVlZFNlcCkge1xuXHQgIGFjYy5wdXNoKFwiXFxuXCIpO1xuXHQgIGFjYy5wdXNoKGluZGVudFN0cihpKSk7XG5cdH0gZWxzZSB7XG5cdCAgbmVlZFNlcCA9IHRydWU7XG5cdH1cblx0YWNjLnB1c2goXCIgXCIpO1xuXHRpZiAoa2V5ID09PSBfXykga2V5ID0gJ+KYhSc7XG5cdGVsc2UgaWYgKGtleSA9PT0gU09BKSBrZXkgPSAnPCc7XG5cdGVsc2UgaWYgKGtleSA9PT0gRU9BKSBrZXkgPSAnPic7XG5cdGVsc2UgaWYgKGtleSBpbnN0YW5jZW9mICRTcGVjaWFsKSBrZXkgPSBrZXkubmFtZTtcblx0ZWxzZSBrZXkgPSBKU09OLnN0cmluZ2lmeShrZXkpO1xuXHRhY2MucHVzaChrZXkpO1xuXHR3YWxrKGkgKyBrZXkubGVuZ3RoICsgMSwgayk7XG4gICAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluZGVudFN0cihpKSB7XG4gICAgcmV0dXJuIG5ldyBBcnJheShpICsgMSkuam9pbignICcpOyAvLyBld3dcbiAgfVxufVxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxubW9kdWxlLmV4cG9ydHMuX18gPSBfXztcbm1vZHVsZS5leHBvcnRzLlNPQSA9IFNPQTtcbm1vZHVsZS5leHBvcnRzLkVPQSA9IEVPQTtcbm1vZHVsZS5leHBvcnRzLiRDYXB0dXJlID0gJENhcHR1cmU7XG5tb2R1bGUuZXhwb3J0cy4kU3BlY2lhbCA9ICRTcGVjaWFsO1xubW9kdWxlLmV4cG9ydHMubWFrZVN0cnVjdHVyZUNvbnN0cnVjdG9yID0gbWFrZVN0cnVjdHVyZUNvbnN0cnVjdG9yO1xubW9kdWxlLmV4cG9ydHMuXyQgPSBfJDtcbm1vZHVsZS5leHBvcnRzLmlzX2VtcHR5VHJpZSA9IGlzX2VtcHR5VHJpZTtcbm1vZHVsZS5leHBvcnRzLmVtcHR5VHJpZSA9IGVtcHR5VHJpZTtcbm1vZHVsZS5leHBvcnRzLmVtYmVkZGVkVHJpZSA9IGVtYmVkZGVkVHJpZTtcbm1vZHVsZS5leHBvcnRzLmNvbXBpbGVQYXR0ZXJuID0gY29tcGlsZVBhdHRlcm47XG5tb2R1bGUuZXhwb3J0cy5tYXRjaFBhdHRlcm4gPSBtYXRjaFBhdHRlcm47XG5tb2R1bGUuZXhwb3J0cy5fdW5pb24gPSB1bmlvbjtcbm1vZHVsZS5leHBvcnRzLnVuaW9uID0gdW5pb25OO1xubW9kdWxlLmV4cG9ydHMuaW50ZXJzZWN0ID0gaW50ZXJzZWN0O1xubW9kdWxlLmV4cG9ydHMuc3VidHJhY3QgPSBzdWJ0cmFjdDtcbm1vZHVsZS5leHBvcnRzLm1hdGNoVmFsdWUgPSBtYXRjaFZhbHVlO1xubW9kdWxlLmV4cG9ydHMubWF0Y2hUcmllID0gbWF0Y2hUcmllO1xubW9kdWxlLmV4cG9ydHMuYXBwZW5kVHJpZSA9IGFwcGVuZFRyaWU7XG5tb2R1bGUuZXhwb3J0cy50cmllUHJ1bmVCcmFuY2ggPSB0cmllUHJ1bmVCcmFuY2g7XG5tb2R1bGUuZXhwb3J0cy50cmllU3RlcCA9IHRyaWVTdGVwO1xubW9kdWxlLmV4cG9ydHMucmVsYWJlbCA9IHJlbGFiZWw7XG5tb2R1bGUuZXhwb3J0cy5jb21waWxlUHJvamVjdGlvbiA9IGNvbXBpbGVQcm9qZWN0aW9uO1xubW9kdWxlLmV4cG9ydHMucHJvamVjdGlvblRvUGF0dGVybiA9IHByb2plY3Rpb25Ub1BhdHRlcm47XG5tb2R1bGUuZXhwb3J0cy5wcm9qZWN0ID0gcHJvamVjdDtcbm1vZHVsZS5leHBvcnRzLnRyaWVLZXlzID0gdHJpZUtleXM7XG5tb2R1bGUuZXhwb3J0cy5jYXB0dXJlVG9PYmplY3QgPSBjYXB0dXJlVG9PYmplY3Q7XG5tb2R1bGUuZXhwb3J0cy50cmllS2V5c1RvT2JqZWN0cyA9IHRyaWVLZXlzVG9PYmplY3RzO1xubW9kdWxlLmV4cG9ydHMucHJvamVjdE9iamVjdHMgPSBwcm9qZWN0T2JqZWN0cztcbm1vZHVsZS5leHBvcnRzLnByZXR0eVRyaWUgPSBwcmV0dHlUcmllO1xuXG4vLyBGb3IgdGVzdGluZ1xubW9kdWxlLmV4cG9ydHMuX3Rlc3RpbmcgPSB7XG4gIHJzdWNjZXNzOiByc3VjY2VzcyxcbiAgcnNlcTogcnNlcSxcbiAgcndpbGQ6IHJ3aWxkLFxuICByd2lsZHNlcTogcndpbGRzZXFcbn07XG4iLCJ2YXIgSW1tdXRhYmxlID0gcmVxdWlyZSgnaW1tdXRhYmxlJyk7XG5cbmZ1bmN0aW9uIFNlYWwoY29udGVudHMpIHtcbiAgdGhpcy5zZWFsQ29udGVudHMgPSBjb250ZW50cztcbiAgT2JqZWN0LmZyZWV6ZSh0aGlzKTtcbn1cblxuU2VhbC5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gKG90aGVyKSB7XG4gIGlmICghKG90aGVyIGluc3RhbmNlb2YgU2VhbCkpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIEltbXV0YWJsZS5pcyh0aGlzLnNlYWxDb250ZW50cywgb3RoZXIuc2VhbENvbnRlbnRzKTtcbn07XG5cbmZ1bmN0aW9uIHNlYWwoY29udGVudHMpIHtcbiAgcmV0dXJuIG5ldyBTZWFsKGNvbnRlbnRzKTtcbn1cblxubW9kdWxlLmV4cG9ydHMuU2VhbCA9IFNlYWw7XG5tb2R1bGUuZXhwb3J0cy5zZWFsID0gc2VhbDtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgUmVmbGVjdCA9IHJlcXVpcmUoXCIuL3JlZmxlY3QuanNcIik7XG5cbm1vZHVsZS5leHBvcnRzLmV4dGVuZCA9IGZ1bmN0aW9uICh3aGF0LCBfd2l0aCkge1xuICBmb3IgKHZhciBwcm9wIGluIF93aXRoKSB7XG4gICAgaWYgKF93aXRoLmhhc093blByb3BlcnR5KHByb3ApKSB7XG4gICAgICB3aGF0W3Byb3BdID0gX3dpdGhbcHJvcF07XG4gICAgfVxuICB9XG4gIHJldHVybiB3aGF0O1xufTtcblxubW9kdWxlLmV4cG9ydHMua3dBcHBseSA9IGZ1bmN0aW9uIChmLCB0aGlzQXJnLCBhcmdzKSB7XG4gIHZhciBmb3JtYWxzID0gUmVmbGVjdC5mb3JtYWxQYXJhbWV0ZXJzKGYpO1xuICB2YXIgYWN0dWFscyA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZm9ybWFscy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBmb3JtYWwgPSBmb3JtYWxzW2ldO1xuICAgIGlmICghKGZvcm1hbCBpbiBhcmdzKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRnVuY3Rpb24gcGFyYW1ldGVyICdcIitmb3JtYWwrXCInIG5vdCBwcmVzZW50IGluIGFyZ3NcIik7XG4gICAgfVxuICAgIGFjdHVhbHMucHVzaChhcmdzW2Zvcm1hbF0pO1xuICB9XG4gIHJldHVybiBmLmFwcGx5KHRoaXNBcmcsIGFjdHVhbHMpO1xufTtcbiJdfQ==